在各种资料中,大家都认为\s等价于 [ \f\n\r\t\v]。如下为菜鸟教程截图:
今天却碰到一个奇怪的问题:
PHP代码,utf-8格式,代码如下:
$pattern_1 = '/\s+?(\S+)?$/';
$pattern_2 = '/[ \f\n\r\t\v]+?(\S+)?$/';$str_1 = '加强和改进党的作风';
$str_2 = '加强和改进你的作风';echo "1:";
echo preg_replace($pattern_1, '', $str_1);echo "<br>2:";
echo preg_replace($pattern_1, '', $str_2);echo "<br>3:";
echo preg_replace($pattern_2, '', $str_1);echo "<br>4:";
echo preg_replace($pattern_2, '', $str_2);
现在就有问题了,为何\s等于 [ \f\n\r\t\v]的话,在对字符串1的替换中,结果却不同?
str_1和str_2没有什么那一个字有什么差别呢,为何正则2对它们的处理结果不同?
由于你正则没有加u,所以匹配的时候不会把utf8字符看成一个字符,而是三个字符
党
这个字,utf8编码是e5859a
,中间的85
,在unicode编码里面是NEL
字符,就是unicode的换行符,如下图
PHP用的正则解析器是PCRE
,PCRE
中\v
代表垂直空白符,所以NEL
字符也被包括在内
如果你要解决这个问题,就在正则后面加u,比如/[ \f\n\r\t\v]+?(\S+)?$/u
以下文字来自官方文档,由于中文翻译有点误导,所以最好直接看英文,Perl 5 no longer includes vertical tab in its set of whitespace characters. The \v escape that was in the Perl documentation for a long time was never in fact recognized. However, the character itself was treated as whitespace at least up to 5.002. In 5.004 and 5.005 it does not match \s.
用正则解析中文的时候一定要注意编码的问题
感谢大佬,就是厉害!
有问题吧?空白字符不止那几个?
那还缺什么呢?
echo preg_replace($pattern_2, '', $str_1);
echo preg_replace($pattern_2, '', $str_2);
这两句,就是把“党”字改了下,就没乱码了,其他都一样,很奇怪,不知道为何有乱码
@html55: 你搜下空白字符都有哪些,我印象中,不知道\b这种的算不算。。。