[解決済み] 文字列中の印刷不可能な文字をすべて削除するには?
質問
0-31と127の文字列を削除する必要があると想像しています。
これを効率的に行うための関数やコードはありますか?
どのように解決するのですか?
7ビットASCII?
もしあなたのターディスが1963年に着陸したばかりで、7ビットの印刷可能なASCII文字が欲しいだけなら、これで0-31と127-255のすべてを切り取ることができます。
$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);
0-31、127-255の範囲にあるものにマッチし、それを削除します。
8ビット拡張ASCII?
ホットタブ・タイムマシーンに落ちて、80年代に戻ってきたんだ。 もしあなたが何らかの形で8ビットASCIIを使用しているなら、文字を128-255の範囲に収めたいと思うかもしれません。0-31と127を探すだけで、簡単に調整できます。
$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);
UTF-8ですか?
ああ、21世紀へお帰りなさい。UTF-8でエンコードされた文字列がある場合は
/u
モディファイア
は正規表現で使用することができます
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);
これは、0-31と127を削除するだけです。これはASCIIとUTF-8で動作し、両方とも
同じ制御セット範囲
(下記のmguttさんの指摘の通り)。厳密に言えば,これは
/u
修飾子を使用します。しかし、他の文字を削除したい場合は、この修飾子があると便利です....
ユニコードを扱う場合は 印刷されない要素が多数ある可能性がある しかし、ここでは簡単なものを考えてみましょう。 ノーブレーク・スペース (u+00a0)
UTF-8の文字列では、これは次のようにエンコードされます。
0xC2A0
. その特定のシーケンスを探して削除することもできますが、その場合は
/u
修飾子を付けるだけで
\xA0
をキャラクタ・クラスに追加します。
$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);
追記:str_replaceはどうなんでしょう?
preg_replace はかなり効率的ですが、もしこの操作を何度も行うのであれば、削除したい文字の配列を作成し、下記の mgutt さんの指摘するように str_replace を使うことができます、例えば。
//build an array we can re-use across several operations
$badchar=array(
// control characters
chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
chr(31),
// non-printing characters
chr(127)
);
//replace the unwanted chars
$str2 = str_replace($badchar, '', $str);
直感的には、これは速いように見えますが、必ずしもそうではありません。ランダムなデータでさまざまな文字列の長さのベンチマークを行ったところ、 php 7.0.12 を使って次のようなパターンが浮かび上がりました。
2 chars str_replace 5.3439ms preg_replace 2.9919ms preg_replace is 44.01% faster
4 chars str_replace 6.0701ms preg_replace 1.4119ms preg_replace is 76.74% faster
8 chars str_replace 5.8119ms preg_replace 2.0721ms preg_replace is 64.35% faster
16 chars str_replace 6.0401ms preg_replace 2.1980ms preg_replace is 63.61% faster
32 chars str_replace 6.0320ms preg_replace 2.6770ms preg_replace is 55.62% faster
64 chars str_replace 7.4198ms preg_replace 4.4160ms preg_replace is 40.48% faster
128 chars str_replace 12.7239ms preg_replace 7.5412ms preg_replace is 40.73% faster
256 chars str_replace 19.8820ms preg_replace 17.1330ms preg_replace is 13.83% faster
512 chars str_replace 34.3399ms preg_replace 34.0221ms preg_replace is 0.93% faster
1024 chars str_replace 57.1141ms preg_replace 67.0300ms str_replace is 14.79% faster
2048 chars str_replace 94.7111ms preg_replace 123.3189ms str_replace is 23.20% faster
4096 chars str_replace 227.7029ms preg_replace 258.3771ms str_replace is 11.87% faster
8192 chars str_replace 506.3410ms preg_replace 555.6269ms str_replace is 8.87% faster
16384 chars str_replace 1116.8811ms preg_replace 1098.0589ms preg_replace is 1.69% faster
32768 chars str_replace 2299.3128ms preg_replace 2222.8632ms preg_replace is 3.32% faster
タイミング自体は1万回繰り返した場合のものですが、より興味深いのは相対的な差です。512文字までは、preg_replaceが常に勝っていました。1-8kbの範囲では、str_replaceが僅かに優勢でした。
面白い結果だと思ったので、ここに載せておきます。 重要なのは、この結果を鵜呑みにしてどの方式を使うかを決めるのではなく、自分のデータと照らし合わせて決めることです。
関連
-
[解決済み】空の配列要素を削除する
-
[解決済み】未定義のメソッド mysqli_stmt::get_result を呼び出す。
-
[解決済み] ある文字列が特定の単語を含んでいるかどうかを確認するにはどうすればよいですか?
-
[解決済み] ずっとUTF-8
-
[解決済み] PHPでユーザー入力をサニタイズするにはどうすればよいですか?
-
[解決済み] PHP 配列をキーではなく値で削除する
-
[解決済み】PHPの'foreach'は実際どのように動作するのですか?
-
[解決済み】英数字以外を削除する方法は?
-
[解決済み】非ASCII文字を半角スペースで置換する方法
-
[解決済み] リファレンス - このシンボルはPHPで何を意味するのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Weird PHP error: 'Can't use function return value in write context'.
-
[解決済み】phpのob_start()の使い道は?
-
[解決済み] PHP & MySQL: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given [重複] PHP & MySQL: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given.
-
[解決済み】PHP定数「PHP_EOL」はいつ使うの?
-
[解決済み】「初期通信パケットの読み込み」でMySQLサーバーに接続できなくなり、システムエラーになる。0
-
[解決済み】未定義の関数mysql_query()をLoginで呼び出す【重複
-
[解決済み】既に開始されているPHPセッション【重複あり
-
[解決済み】file_get_contents( )が動作しない。
-
[解決済み] PHPで文字列からすべてのスペースを取り除くにはどうすればよいですか?重複
-
[解決済み] ファイル名の文字列サニタイザー