preg_split vs mb_split

emk*_*y08 7 php regex pcre split

根据PHP手册,uPCRE正则表达式的修饰符支持对模式和主题字符串的UTF-8支持.

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


作为一个例子,考虑preg_splitvs mb_split:两者

preg_split('/' . $pattern . '/u', $string);
Run Code Online (Sandbox Code Playgroud)

mb_split($pattern, $string);
Run Code Online (Sandbox Code Playgroud)

似乎返回相同的结果.那么,应该首选哪一个?它甚至重要吗?

Cas*_*yte 10

主要区别在于preg_函数使用pcre库,当mb_ereg_函数(包括mb_split)使用oniguruma库(在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
  • 字符类中的非转义方括号:[][]当pcre看到包含]和的字符类时,Oniguruma 看作两个空字符类[
  • \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一点.


为了使换行与点匹配m,当PCRE使用s修饰符时,Oniguruma使用修饰符.在mb_ereg_函数中,默认情况下,点匹配换行符.(因此m默认情况下修改器处于启用状态).

PCRE使用s修饰符将换行符与点匹配.该m修改中表现不同PCRE,它改变的意义^,并$从"开始"和字符串为"开始"和该行的"结束"的"结束"锚.

使用Oniguruma,这些锚点的含义不会改变,它们始终匹配线条的起点和终点.为了匹配字符串的限制,它使用\A并且\z也可以与PCRE一起使用.

请注意Oniguruma已经分叉,以提供实现更多Perl功能和语法元素的Onigmo(在当前的Ruby版本中使用),这与PCRE更相似.