2013-02-18 10 views
7

jsの次はなぜコードワード:バグ:ルック周りUnicodeの問題

"آرد@".replace(/(?=.)/g,'!'); // returns: ""!آ!ر!د"" 

しかし、そのPHPの相当'!�!�!�!�!�!�'を返しますか?

preg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�' 

これは4.3.5 - 5.0.5,5.1.1 - 5.1.6のバージョンでのみ動作します。

を参照してください:あなたは、単に/u修飾子を追加する場合http://3v4l.org/jrV0W

+0

@ PHPのバージョンで何をしますか?それはまた "/(?=.)/"でなければならない?前に私がそれを見たことのないように本当に尋ねる。 – kufudo

+1

'@'は無効な区切り文字です。 [PHP](http://www.php.net/manual/en/regexp.reference.delimiters.php)の区切り文字のページを確認してください。 – hjpotter92

+2

@BackinaFlash有効です! – PHPst

答えて

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; //? 

アウトは入れ:

###### 
### 
#�#�#�#�#�#� 
#�#�#�#�#�#� 
#آ#ر#د 
#آ#ر#د 
+0

バグはありませんでした。あなたは実際に私の答えを読んだ?私はドットが付いた行がなぜ動かないのかを説明します –

+0

@TomSarduy私の例で見てきたように、 '/./u'は見た目に置かれたときに期待しています。 – PHPst

4

を、パターンがutf-8として扱われることになっています。第二の例があるために動作します:PHP 5.1以来

  1. 、あなたに翻訳することができ\p{L}使用することができます。「を任意の言語からの手紙のいずれかの一種です。」
  2. 標準表記に加えて、\ p {L}、Java、Perl、PCRE、今度はPHPは、簡略\pLを使用できます。この短縮形は、単一文字のUnicodeプロパティでのみ機能します。

UPDATE:はなぜpreg_replace('/(?=.)/u', '!', 'آرد'); //returns '!�!�!�!�!�!�'??

@MarkFoxが言うようにpreg_replace()の文脈で、それは1文字あたりのバイト、あなたは「RegExing」している文字を想定しているので、理由があり、マルチバイトあります。だからあなたの置換えの出力は、あなたが期待している一致の倍を持っています。それは各文字の各バイト(2バイトであると推測しています)と一致しています -

あなたはあなたの文書エンコーディングに関係なく、 Unicode character propertiesこの作業を行うには。

奇妙なシンボルはどうですか?

"疑問符の内側に奇妙な四角い記号"が表示されている場合は、通常、置換文字として知られています。これは通常、80-FF(128-255)の範囲のバイトと、システムはUTF-8にレンダリングしようとしています。

UTF-8の全バイト範囲が1バイト文字に対して無効ですが、すべてが西洋のエンコードでは、ISO-8859-1など非常に一般的です。

+2

答えは\ pLがpreg_replaceで動作する理由を説明しています。理由は、ドット '。' preg_replaceの文脈では、1文字あたり1バイトと見なし、あなたがRegExingしている文字がマルチバイトであるためです。だからあなたの置換えの出力があなたが期待していた2倍の一致を持っているのです。それは各文字の各バイト(2バイトであると推測しています)と一致しています。 –

+0

@PHPst:MarkFoxは本当に正しいです、実際には、私の答えの一部になります:D –

+0

@PHPst:真実ではないのですか?私はすべてがそこにあると思う。 –