首页 > 解决方案 > 我什么时候需要在 PHP 正则表达式中使用 u-modifier?

问题描述

我知道,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,对吗?

谁能告诉我,如果我忽略了什么?

标签: phputf-8preg-replacepreg-matchpcre

解决方案


第一个表达式没有问题。被量化的字符是明确的单字节,并且不能出现在 UTF-8 多字节序列中。

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

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

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

这更危险:

echo preg_replace('/^(.)/', "0", "");
// => 0???

通常,如果不了解 UTF-8 的工作原理,可能很难预测哪些正则表达式是安全的,哪些不安全,因此/u对所有可能包含 U+007F 以上字符的文本使用是最佳实践。


推荐阅读