我想知道PCRE如何检测来自任何语言的单词字符。 我正在测试这个字符串:
"間違つ"
php文件编码为UTF-8,并在内容类型标记中使用Charset = UTF-8正确标记。
<?php
$string="\xE9\x96\x93\xE9\x81\x95\xE3\x81\xA4"; //Bytestream from "間違つ"
$string=preg_replace('/\w/','\w',$string);
echo $string;
echo "<br>";
$byte="\xE9"; //I've tried with each byte separately to find word characters
if(preg_match('/\w/',$byte)){
echo "$byte is a word";
}
else{
echo "$byte is not a word";
}
?>
所有字节中的 "\xE9" "\xE9" "\xE3"
都是单词。
显示:
我知道为什么符号会出现。
解码器使用Unicode替换字符,代码点FFFD,
作为无效UTF-8序列的解码而不是停止处理文本。
由于一个“单词字符”被替换'\w'
替换,因此存在无效序列
然后它打破了“字节安全”来显示。
所以问题是:
如果这些字符不是有效的UTF-8序列,为什么这些字符会匹配?
如何知道哪些字符真的是所有Unicode集的字符?
答案 0 :(得分:2)
我相信你的正则表达式引擎正在解释你的字节流,好像它们是在ISO Latin-1中编码的(它们不是)。在ISO Latin-1中,
E3
是带有TILDE的LATIN SMALL LETTER E9
是LATIN SMALL LETTER E WITH ACUTE 是“单词”字符,但
A4
是CURRENCY SIGN 81
,93
,95
和96
为C1 control characters 不是单词字符。
您可以在正则表达式上设置/u
修饰符,以请求它使用UTF-8而不是Latin-1。请参阅PHP manual on pattern modifiers。
答案 1 :(得分:2)
你必须设置u
-Flag否则它被解释为ISO-8859-1字符串。
以下脚本显示哪些字符\w
在没有u
的情况下匹配 - 标记:
header("Content-Type: text/plain");
$i = 255;
while($i--)
{
preg_match('/\w/S', chr($i), $m);
printf("%' 1s \x%s\n", $m[ 0 ], strtoupper(bin2hex($m[ 0 ])));
}
如果\w
- 设置了标记,则[{1}}仅匹配[a-zA-Z]:
u
注意:如果// added 'A' at the beginning and 'B' at the end
preg_match_all('/\w/u', "A\xE9\x96\x93\xE9\x81\x95\xE3\x81\xA4B", $m);
print_r($m);
- 标志存在,preg_ *将静默无法解析字符串,如果它包含非unicode-chars(例如\ x80- \ xFF)。< / p>