漢字|質問|中国語
著者: bluedoor
元の投稿アドレス: http://www.anbbs.com/anbbs/index.php?f_id=3&page=1
私はこの 2 日間、キーワード強調プログラムに取り組んでいます。書かれたプログラムはローカルです。テストも行います。はうまくいきましたが、ページに行くと文字化けの山があり、ハイライトどころか文字を読むこともできませんでした。
間違いを探して調べてみたところ、英語は問題ありませんでしたが、漢字に遭遇すると問題が発生しやすく、漢字に遭遇すると問題が避けられない場合もありました。
要約すると、
preg_match_all($pat,...) や preg_replace($pat,...) などのパターンマッチングを使用する場合...
問題が発生しやすい状況は次のとおりです。
preg_match_all("/( 漢字)+/ism","I am a Chinese Character, let's see what you do to me! ",$m_a);
このパターンは、「漢字」とのマッチングが非常に簡単です。この場合、漢字を含むパターンは正常に一致しますが、結果が不確かなので、あまり早く満足しないでください。
問題は次のように発生する必要があります:
preg_match_all("/[漢字]+/ism","I am a Chinese Character, let's see what you do to me!",$m_a);
I want to match the 「汉」と「字」または「漢字」の出現。これにより、マッチング結果が文字化けし、無限ループが発生する可能性があります。なぜこのようなことが起こるのでしょうか?これは、PHP が内部で UNICODE を使用しておらず、マルチバイト テキストをサポートしていないため、パターン マッチングでは「漢字」が 4 バイトの ASCII として扱われるためです。エラーが発生しないのはおかしいでしょう。
その後、パターンマッチングを書き直そうとしたところ、問題を解決できると思われる (なぜらしいと言うのか? 後で見てください) メソッドを見つけました:
preg_match_all("/(汉|字)+/ism","I am a Chinese Character, Let's see what you do to me! ",$m_a);
このように書くと、「汉」、「字」、または「汉字」に一致し、結果は $m_a
Array
(
[0 ] => 配列
(
[0] => 漢字
)
[1] => 配列
(
[0] => 漢字
)
)
完全に一致する文字列が表示されるのはどうでしょうか。しかし、喜ぶのは時期尚早で、実際に使用すると問題が発生することもよくあります。もう一度問題を探したところ、ついに問題の根本が見つかりました。 PHPはマルチバイトテキストをサポートしていないため、パターンマッチングと文字操作は内部コード変換後に実行されます(これが正しいかどうかはわかりません)例は次のとおりです:
eregi_replace("性"," No", "responsible"); この操作は、文字列 "responsible" 内の単語 "sex" を "no" に置き換えることです。 「責任感」に「性別」はないので、置換操作を実行せずに「責任感」を返すはずが、結果は「責任感」だった!
予想外でした!なぜ? ASCIIコードを見てみると分かりますが、211,208(責任)、212,240(責任)、184,208(意味)という漢字がコード化されています。そして、「sex」「エンコードは 208,212 (sex) で、これはたまたまコードの 2 バイト目と 1 バイト目の組み合わせと一致しています。つまり、PHP は、一致する同じパターンを見つけて、中国語の文字を半分に分割し、置換された文字列と結合することを知っていたため、何か問題が発生しました。
その時は、最も一般的に使用される str_replace() は問題ないと思っていましたが、実は同じ操作を実行すると str_replace() もエラーを起こします。以前に漢字置換を行っていて本当に良かったと今では思います。おそらく、このとき行われた漢字置換は比較的長い漢字列であったため、上記のような事態は起こりにくいと考えられます。たとえ何も問題がなかったとしても、安全ではないことを知ってください。
問題はある、そして私たちは働き続けなければならない、私たちが乗り越えなければならない唯一の困難は今の私たちです。
幸いなことに、私は一連の PHP 拡張モジュール、Multibyte String Functions を思い出しました。これは、次のようなマルチバイト テキスト操作をサポートする多くの関数を追加します。 ereg_replace() は mb_ereg_replace() に対応します。特定の機能の説明については、関連記事を参照してください。
要約: 漢字を安全に操作するには、マルチバイト文字列関数を使用するのが最善です。