以下の js コード ワードを使用する理由:
"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د""
しかし、それに相当する php は'!�!�!�!�!�!�'
?を返します。
preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'
これは、4.3.5 - 5.0.5、5.1.1 - 5.1.6 バージョンでのみ機能します。
以下の js コード ワードを使用する理由:
"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د""
しかし、それに相当する php は'!�!�!�!�!�!�'
?を返します。
preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'
これは、4.3.5 - 5.0.5、5.1.1 - 5.1.6 バージョンでのみ機能します。
修飾子を追加するだけ/u
で、パターンはとして扱われることになりますutf-8
。2番目の例は、次の理由で機能します。
\p{L}
と翻訳できるものを使用できます。\pL
。省略形は、1文字のUnicodeプロパティでのみ機能します。更新:なぜpreg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'??
@MarkFoxが言うように、その理由は、そのコンテキストではpreg_replace()
、文字ごとに1バイトを想定しており、「RegExing」している文字はマルチバイトであるためです。そのため、置換出力は期待する2倍の一致を示し、各文字の各バイトに一致します(2バイトと推測されます)-
ドキュメントエンコーディングで何をする場合でも、これを機能させるにはUnicode文字プロパティを使用する必要があります。
その奇妙なシンボルはどうですか?
REPLACEMENT CHARACTERとも呼ばれる「内部に疑問符が付いた奇妙な正方形の記号」が表示された場合、これは通常、80-FF(128-255)の範囲のバイトがあり、システムがレンダリングしようとしていることを示します。でUTF-8
。
そのバイト範囲全体は、のシングルバイト文字には無効ですがUTF-8
、などの西洋のエンコーディングではすべて非常に一般的ISO-8859-1
です。
いくつかの文字列をテストした後、PREGエンジンにバグがあると思います。最初の3行は期待どおりに出力されますが、4行目には障害があります。
<?php
echo preg_replace('/./' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/./u' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/(?=.)/' , '#', 'آرد') . PHP_EOL; //✓
echo preg_replace('/(?=.)/u' , '#', 'آرد') . PHP_EOL; //✗
echo preg_replace('/(?=\pL)/' , '#', 'آرد') . PHP_EOL; //?
echo preg_replace('/(?=\pL)/u', '#', 'آرد') . PHP_EOL; //?
出力:
######
###
#�#�#�#�#�#�
#�#�#�#�#�#�
#آ#ر#د
#آ#ر#د