php正则expression式在UTF-8中的词边界匹配
我有一个utf-8 php文件中的以下php代码:
var_dump(setlocale(LC_CTYPE, 'de_DE.utf8', 'German_Germany.utf-8', 'de_DE', 'german')); var_dump(mb_internal_encoding()); var_dump(mb_internal_encoding('utf-8')); var_dump(mb_internal_encoding()); var_dump(mb_regex_encoding()); var_dump(mb_regex_encoding('utf-8')); var_dump(mb_regex_encoding()); var_dump(preg_replace('/\bweiß\b/iu', 'weiss', 'weißbier'));
我想最后一个正则expression式只replace完整的单词而不是单词的一部分。
在我的Windows电脑上,它返回:
string 'German_Germany.1252' (length=19) string 'ISO-8859-1' (length=10) boolean true string 'UTF-8' (length=5) string 'EUC-JP' (length=6) boolean true string 'UTF-8' (length=5) string 'weißbier' (length=9)
在networking服务器(linux)上,我得到:
string(10) "de_DE.utf8" string(10) "ISO-8859-1" bool(true) string(5) "UTF-8" string(10) "ISO-8859-1" bool(true) string(5) "UTF-8" string(9) "weissbier"
因此,正则expression式正如我所期望的在Windows上,而不是在Linux上。
所以主要的问题是,我应该如何编写我的正则expression式来匹配单词边界?
第二个问题是我如何让Windows知道我想在我的PHP应用程序中使用utf-8。
即使在UTF-8模式下,像\w
和\b
这样的标准类别简写符号也不支持Unicode。 你只需要使用Unicode的简写,但是你可以通过使用lookarounds而不是使用替代方法来使它变得不那么丑陋:
/(?<!\pL)weiß(?!\pL)/u
还要注意我是如何将Unicode花括号放在Unicode类中的; 当class级名称由单个字母组成时,可以这样做。
这是我迄今为止发现的。 通过重写这样的search和replace模式:
$before = '(^|[^\p{L}])'; $after = '([^\p{L}]|$)'; var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weißbier')); // Test some other cases: var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weiß')); var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', 'weiß bier')); var_dump(preg_replace('/'.$before.'weiß'.$after.'/iu', '$1weiss$2', ' weiß'));
我得到想要的结果:
string 'weißbier' (length=9) string 'weiss' (length=5) string 'weiss bier' (length=10) string ' weiss' (length=6)
在我的Windows计算机运行Apache和托pipe的Linuxnetworking服务器运行Apache。
我认为有一些更好的方法来做到这一点。
另外,我还想将我的windows电脑设置为utf-8。
猜猜这与Bug#52971有关
像
\b
\w
这样的PCRE-Meta-Characters不能使用Unicodestring。
并在PHP 5.3.4中修复
PCRE扩展: 修正了错误#52971 ( PCRE-Meta-Characters与 UTF -8无法使用 )。
根据这个评论 ,这是PHP中的一个错误。 使用\W
而不是\b
给予任何好处?