根据PHP手册,PCRE正则表达式的u修饰符支持对模式和主题字符串的UTF-8支持。
考虑到这一点,使用带有u修饰符的PCRE表达式与相应的mb_*多字节字符串函数有什么区别吗?(假设所有字符串都是UTF-8编码的。)
作为一个例子,请考虑preg_split与mb_split:
preg_split('/' . $pattern . '/u', $string);和
mb_split($pattern, $string);似乎返回相同的结果。那么,哪一个应该是首选呢?这有关系吗?
发布于 2016-03-20 17:02:57
主要的区别是preg_函数使用pcre库,当mb_ereg_函数(包括mb_split)使用oniguruma图书馆 (在2.0版本之前在ruby中使用)。
主要原因是,oniguruma可以处理多个编码(ASCII、UTF-8、UTF-16 10、UTF-16 10、UTF-32BE、UTF-32 10、EUC-JP、EUC-TW、EUC-KR、EUC-CN、Shift_JIS、Big5、GB18030、KOI8 8-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)
请注意,mb_函数(如mb_detect_encoding )可用的编码很多不在此列表中(例如,UTF-7、ArmSCI-8、CP866 ),从而限制了mb_ereg_函数的相关性。(因为您需要在处理字符串之前将其转换为受支持的编码,然后再将其转换回来。)
这两个regex引擎或多或少都有相同的特性,尽管如此,您还是可以找到一些不同之处(并非详尽无遗):
猫头鹰不支持:
\pN被看作是pN,您需要编写:\p{N}]和[的字符类时,将[视为两个空字符类。\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是嵌套级别。为了将换行符与点匹配,当m使用s修饰符时,Oniguruma使用s修饰符。在mb_ereg_函数中,默认情况下,点与换行符匹配。(因此默认情况下m修饰符是打开的)。
PCRE使用s修饰符将换行符与点匹配。m修饰符在PCRE中的行为不同,它将^和$锚点的含义从字符串的“开始”和“结束”更改为行的“开始”和“结束”。
对于Oniguruma,这些锚的含义不会改变,它们总是匹配行的开始和结束。为了匹配字符串的限制,它使用了\A和\z,这两种方法也适用于PCRE。
请注意,Oniguruma是为了给Onigmo提供实现更多Perl特性和语法元素的Onigmo(在当前Ruby版本中使用),这与PCRE更相似。
发布于 2016-03-20 15:47:08
只要您严格使用UTF-8,您就可以接受这两种方法。如果您使用的是另一个charset,那么建议使用mb_split(),因为带有u的u修饰符不允许您指定charset,而是将字符串视为UTF-8。
关于扩展和长期生存能力,我建议从一开始就使用mb_split(),这样您就可以在以后使用或需要UTF-8以外的东西时被覆盖。
https://stackoverflow.com/questions/36115796
复制相似问题