根据PHP manual,PCRE正则表达式的u
修饰符启用对模式和主题字符串的UTF-8支持。
考虑到这一点,将PCRE表达式与u
修饰符一起使用和相应的mb_*
多字节字符串函数之间有什么区别吗? (假设所有字符串都是UTF-8编码的。)
例如,考虑preg_split
与mb_split
:两者
preg_split('/' . $pattern . '/u', $string);
和
mb_split($pattern, $string);
似乎返回相同的结果。那么,应该首选哪一个呢?甚至有关系吗?
最佳答案
主要区别在于preg_
函数使用pcre library,而mb_ereg_
函数(包括mb_split
)使用oniguruma library(在2.0版之前的ruby中使用)。
主要原因是oniguruma可以处理多种编码(ASCII,UTF-8,UTF-16BE,UTF-16LE,UTF-32BE,UTF-32LE,EUC-JP,EUC-TW,EUC-KR,EUC-CN, Shift_JIS,Big5,GB18030,KOI8-R,CP1251,ISO-8859-1,ISO-8859-2,ISO-8859-3,ISO-8859-4,ISO-8859-5,ISO-8859-6,ISO- 8859-7,ISO-8859-8,ISO-8859-9,ISO-8859-10,ISO-8859-11,ISO-8859-13,ISO-8859-14,ISO-8859-15,ISO-8859- 16)当pcre不能。
请注意,此列表中未包含可用于mb_
函数(例如mb_detect_encoding
)的许多编码(例如,UTF-7,ArmSCII-8,CP866),这限制了mb_ereg_
函数的相关性。 (因为您需要先将字符串转换为受支持的编码,然后再进行处理,然后再将其转换回。)
这两个正则表达式引擎或多或少都具有相同的功能,但是您会发现一些区别(并不是很详尽):
Oniguruma不支持:
\pN
被视为pN
,您需要编写:\p{N}
[][]
视为两个空字符类,当pcre看到包含]
和[
的字符类\K
功能\R
别名(?P<name>...)
命名的组。仅允许使用(?<name>...)
或(?'name'...)
。 \g<name>
(不允许Perl语法(?&name)
和(?1)
或(?R)
)。 PCRE不支持:
(?J)
修饰符来启用此功能。 \k<...>
语法编号了反向引用。您可以编写\k<name>
,但不能编写\k<1>
或\k<-1>
。 \k<name+n>
做到这一点,其中n
是嵌套级别。 为了使换行符与点匹配,当PCRE使用
m
修饰符时,Oniguruma使用s
修饰符。在
mb_ereg_
函数中,默认情况下,点与换行符匹配。 (因此m
修饰符默认情况下处于启用状态)。PCRE使用
s
修饰符将换行符与点匹配。 m
修饰符在PCRE中的行为有所不同,它将^
和$
anchor 的含义从字符串的“start”和“end”更改为该行的“start”和“end”。使用Oniguruma时,这些 anchor 的含义不会改变,它们始终与行的开头和结尾匹配。为了匹配字符串的限制,它使用了PCRE也提供的
\A
和\z
。请注意,Oniguruma已被 fork 以提供实现更多Perl功能和语法元素的Onigmo(在当前的Ruby版本中使用),并且与PCRE更相似。