ホームページ >php教程 >php手册 >ヒント: 漢字の置換とパターン マッチングに関する PHP の問題

ヒント: 漢字の置換とパターン マッチングに関する PHP の問題

WBOY
WBOYオリジナル
2016-06-21 09:01:191086ブラウズ

この 2 日間、キーワードを強調表示するプログラムを作成していました。作成したプログラムはローカルでテストするとうまく動作しましたが、ページにアクセスすると、強調表示どころか文字化けが山積みになってしまいました。 、それはただ単にそれが見えないだけでした!

エラーを探したところ、英語では問題ないことがわかりましたが、中国語の文字に遭遇すると問題が発生しやすく、中国語の文字に遭遇すると問題が発生する場合があります。

要約すると:

preg_match_all($pat,…) や preg_replace($pat,…) などのパターン マッチングを使用する場合…

簡単 問題は次のとおりです
preg_match_all("/(漢字)+/ism","私は漢字です。あなたが私に何をするか見てみましょう!",$m_a);
このパターンは非常に単純です。 「漢字」に一致します。この場合、漢字を含むパターンは正常に一致しますが、結果が不確かなので、あまり早く満足しないでください。

問題は次のように発生するはずです:
preg_match_all("/[漢字]+/ism","私は漢字です。あなたが私に何をするか見てみましょう!",$m_a);
「汉」に一致させたいのですが、「字」または「汉字」が表示されます。これにより、マッチング結果が文字化けし、無限ループが発生する可能性があります。なぜこのようなことが起こるのでしょうか?これは、PHP が内部で UNICODE を使用しておらず、マルチバイト テキストをサポートしていないため、パターン マッチングでは「漢字」が 4 バイトの ASCII として扱われるためです。エラーが発生しないのはおかしいでしょう。

その後、パターン マッチングを書き直そうとしたところ、問題を解決できると思われる (なぜらしいと言うのでしょうか? 後で見てください) メソッドを見つけました。
preg_match_all("/(汉|字)+/ism " ,"私は中国人です。あなたが私に何をするか見てみましょう!",$m_a);

このように書くと、「汉」、「字」、または「汉字」に一致し、結果は $ になります。 m_a

配列
(
[0] => 配列
(
[0] => 漢字
)

[1] = > >(
[0] => 単語
)

)

完全に一致する文字列が表示されるのはどうでしょうか。しかし、喜ぶのはまだ早く、実際に使用すると問題が発生することがよくあります。もう一度問題を探したところ、ついに問題の根本が見つかりました。 PHP はマルチバイト テキストをサポートしていないため、パターン マッチングと文字操作は内部コード変換後に実行されます (これが正しいかどうかはわかりません)。例:

eregi_replace(" Sex", "no) ", "responsibility"); この操作は、文字列 "responsibility" 内の単語 "sex" を "no" に置き換えることです。最終的な結果はどうなりますか? 「責任感」に「性別」はないので、置換操作を実行せずに「責任感」を返すはずが、結果は「責任感」だった!

予想外でした!なぜ? ASCIIコードを見てみると分かりますが、211,208(責任)、212,240(責任)、200,206(任意)、184,208(意味)という漢字がコード化されています。 >

「sex」のエンコードは 208,212 (sex) ですが、これは偶然にもいくつかの 2 バイト目と 1 バイト目の組み合わせと一致します。つまり、PHP は、一致する同じパターンを見つけて、中国語の文字を半分に分割し、置換された文字列と結合することを知っていたため、何か問題が発生しました。

その時は、最も一般的に使用される str_replace() は問題ないと思っていましたが、実際には str_replace() も同じ操作を実行するとエラーになります。以前に漢字置換を行っていて本当に良かったと今では思います。おそらく、このとき行われた漢字置換は比較的長い漢字列であったため、上記のような事態は起こりにくいと考えられます。たとえ何も問題がなかったとしても、安全ではないことを知ってください。

問題はありますが、私たちが乗り越えなければならない唯一の困難は、現在の私たちです。

幸いなことに、私は一連の PHP 拡張モジュール、Multibyte String Functions を思い出しました。これは、次のようなマルチバイト テキスト操作をサポートする多くの関数を追加します。 ereg_replace() は mb_ereg_replace() に対応します。特定の機能の説明については、関連記事を参照してください。

要約: 漢字を安全に操作するには、マルチバイト文字列関数を使用するのが最善です。



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。