多字节字符串和 php 正则表达式的奇怪行为

Weird behaviour with multibyte strings and php regex

我正在使用预匹配 php 并发现了一些奇怪的行为,如下所示(行为似乎在任何版本中都是一致的):

var_dump(preg_match('/[£]/', '«')); // true
var_dump(preg_match('/£/', '«')); // false

var_dump(preg_match('/[»]/', '«')); // true
var_dump(preg_match('/»/', '«')); // false

我希望所有这些表达式都为 return false,但是当在正则表达式中使用方括号时(意味着匹配此集合中的任何字符),正则表达式 return 为真。我确实事先检查过是否支持多字节字符串,并被告知是这种情况,但我可能弄错了?我通常会使用 mb_ereg 替代方案,但是 preg_replace_callback 没有我想要使用的替代方案。归根结底,我只想知道这里发生了什么,我找到了一个解决方法,所以这不是什么大问题,但这看起来真的很奇怪!

您必须为这些测试添加 UTF-8 标志,即 '/[£]/u'

来自PHP docs

u (PCRE_UTF8) This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern and subject strings are treated as UTF-8. An invalid subject will cause the preg_* function to match nothing; an invalid pattern will trigger an error of level E_WARNING. Five and six octet UTF-8 sequences are regarded as invalid since PHP 5.3.4 (resp. PCRE 7.3 2007-08-28); formerly those have been regarded as valid UTF-8.