根据PHP manual,PCRE正则表达式的u修饰符启用对模式和主题字符串的UTF-8支持。

考虑到这一点,将PCRE表达式与u修饰符一起使用和相应的mb_*多字节字符串函数之间有什么区别吗? (假设所有字符串都是UTF-8编码的。)

例如,考虑preg_splitmb_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不支持:

  • 要写的不带花括号的一个字母unicode速记字符类。例如:\pN被视为pN,您需要编写:\p{N}
  • Unicode字符类:Xan,Xps,Xsp,Xwd
  • 字符类中的
  • 非转义方括号:Oniguruma将[][]视为两个空字符类,当pcre看到包含][的字符类
  • \K功能
  • 换行序列的\R别名
  • 使用Python语法(?P<name>...)命名的组。仅允许使用(?<name>...)(?'name'...)
  • 组引用的内容不是Oniguruma语法:\g<name>(不允许Perl语法(?&name)(?1)(?R))。
  • 回溯控制动词

  • PCRE不支持:
  • 复制了命名组(默认情况下)。您需要使用(?J)修饰符来启用此功能。
  • \k<...>语法编号了反向引用。您可以编写\k<name>,但不能编写\k<1>\k<-1>
  • 向后引用到特定的嵌套级别。 Oniguruma可以使用\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更相似。

    09-25 17:25