7

preg_replaceを使用して、文字列入力から日本語の全幅の空白 "  "を削除しようとしていますが、マルチバイト文字列が破損してしまいます。

str_replaceではなくpreg_replaceを使用したいと思います。サンプルコードは次のとおりです。

$ keyswords='ラメ単色';
$ keyswords = str_replace(array(''、'')、''、urldecode($ keyswords)); //出力:'ラメ単色'

$ keyswords = preg_replace( "@ [] @"、''、urldecode($ keyswords)); //出力:'����単色'

なぜそうなのか、そしてこの状況をどのように改善するのかについて、誰かが何か考えを持っていますか?

4

4 に答える 4

9

uフラグを正規表現に追加します。これにより、RegEx エンジンは入力文字列を UTF-8 として扱います。

$keywords = preg_replace("@[  ]@u", ' ',urldecode($keywords));
// outputs :'ラメ単色'

コードパッド

文字列をマングルする理由は、正規表現エンジンにとって、置換文字20(スペース) またはe3 80 80(IDEOGRAPHIC SPACE) が 2 つの文字として扱われず、別々のバイト20,e380.

スキャンする文字列のバイト シーケンスを見ると、e3 80 80 e3 83 a9 e3 83 a1 e5 8d 98 e8 89 b2. 最初の文字が IDEOGRAPHIC SPACE であることはわかっていますが、PHP はそれを一連のバイトとして扱っているため、正規表現エンジンがスキャンしている個々のバイトと一致するため、最初の 4 バイトを個別に置換します。

� (REPLACEMENT CHARACTER) をもたらすマングリングについては、バイトが文字列のさらに先にあるために発生することがわかりe3ます。このバイトは、 (KATAKANA LETTER RA)e3などの 3 バイト長の日本語文字の開始バイトです。e3 83 a9その先頭e3を (スペース) に置き換えると20、有効な UTF-8 シーケンスではなくなります。

フラグを有効にするuと、RegEx エンジンは文字列を UTF-8 として扱い、文字クラス内の文字をバイト単位で処理しなくなります。

于 2012-12-19T06:22:12.893 に答える
2

追加の問題を回避するために、内部エンコーディングを明示的に mb_* 関数ソリューションに設定することも検討してください。

mb_internal_encoding("UTF-8");
于 2012-12-19T06:32:00.740 に答える
1

ドキュメントを掘り下げるのは常に良いことです。preg_* 関連の関数がマルチバイト文字に最適化されていないことがわかりました。代わりに mb_ereg_* および mb_* 関数が使用されることになっています。コードを次のようにリファクタリングすることで、この小さな問題を解決しました。

$keywords = 'ラメ単色';
$pattern = " "/*ASCII 空白*/ . " "/*マルチバイト空白*/;
$キーワード = トリム(
    mb_ereg_replace("[{$pattern}]+", ' ',urldecode($keywords))); // 出力:'ラメ単色'

ありがとうございます!

于 2012-12-19T06:22:04.093 に答える
-1

これを使って

$keywords = preg_replace('/\s+/', ' ',urldecode($keywords));
于 2012-12-19T06:30:50.320 に答える