什么时候需要在PHP正则表达式中使用u-modifier?

时间:2019-09-26 03:55:32

标签: php utf-8 preg-replace preg-match pcre

我知道,PHP PCRE函数将字符串视为字节序列,因此许多站点建议使用/u修饰符将输入和正则表达式作为UTF-8处理。

但是,我真的真的总是需要吗?我的测试表明,当我不使用转义序列或点或类似符号时,此标志没有任何作用。

例如

preg_match('/^[\da-f]{40}$/', $string);检查字符串是否具有SHA1哈希格式

preg_replace('/[^a-zA-Z0-9]/', $spacer, $string);替换每个非ASCII字母或数字的字符

preg_replace('/^\+\((.*)\)$/', '\1', $string);用于获取+(XYZ)的内部内容

这些正则表达式仅包含单字节ASCII符号,因此无论输入哪种格式,它都应该在每个输入上起作用,不是吗?请注意,第三个正则表达式使用点运算符,但是当我在字符串的开头和结尾切掉一些ASCII字符时,这也应该在UTF-8上起作用,对吗?

没有人告诉我,如果我忽略了什么吗?

2 个答案:

答案 0 :(得分:2)

第一个表达式没有问题。要量化的字符明确为单字节,不能以UTF-8多字节序列出现。

第二种表达可能会给您比预期更多的间隔;例如:

prompt('Please type a ' + typeOfSpeechNeeded + ', ' + questions-- + ' question(s) left')

第三个表达式也没有问题,因为重复的字符受括号限制(这是ASCII安全的)。

这更危险:

echo preg_replace('/[^a-zA-Z0-9]/', "0", "?");
// => 0000

通常,在不了解有关UTF-8如何工作的情况下,很难预测哪个正则表达式是安全的,哪些不是安全的,因此对可能包含U + 007F以上字符的所有文本使用echo preg_replace('/^(.)/', "0", "?"); // => 0??? 是最佳做法。

答案 1 :(得分:-1)

  

u(PCRE_UTF8)
  此修改器打开了与Perl不兼容的PCRE的其他功能。模式和主题字符串被视为UTF-8。无效的主题将导致preg_ *函数不匹配。无效的模式将触发E_WARNING级别的错误。自PHP 5.3.4起(分别为PCRE 7.3 2007-08-28),五个和六个八位字节的UTF-8序列被视为无效;以前被认为是有效的UTF-8。

当您必须比较Unicode字符(例如韩语或日语)时,将需要此。

换句话说,除非您不比较不是Unicode的字符串(例如英语),否则不需要使用此标志。