preg_split 对比 mb_split
preg_split vs mb_split
根据 PHP manual,PCRE 正则表达式的 u
修饰符为模式和主题字符串启用 UTF-8 支持。
考虑到这一点,使用带有 u
修饰符的 PCRE 表达式和相应的 mb_*
多字节字符串函数有什么区别吗? (假设所有字符串都是 UTF-8 编码。)
例如,考虑 preg_split
与 mb_split
:两者
preg_split('/' . $pattern . '/u', $string);
和
mb_split($pattern, $string);
似乎return 相同的结果。那么,应该优先选择哪一个呢?这有关系吗?
只要您严格按照 UTF-8
工作,您都可以。如果您使用另一个 charset
,那么建议使用 mb_split()
,因为 PCRE 的 u
修饰符不允许您指定 charset
,而是将字符串视为UTF-8
.
关于扩展和长期生存能力,我建议从一开始就使用 mb_split()
,以便在以后使用或需要 UTF-8
以外的东西时,您可以得到保障。
主要区别在于preg_
函数使用pcre library, when the mb_ereg_
functions (including mb_split
) use the 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)限制了 [=11 的相关性=] 功能。 (因为您需要先将字符串转换为受支持的编码,然后再将其转换回来。)
这两个正则表达式引擎或多或少具有相同的功能,但是您可以找到一些不同之处(并非详尽无遗):
Oniguruma 不支持:
- 一个字母unicode shorthand字符class要写成没有大括号。
例如:\pN
被看作pN
,你需要写:\p{N}
- unicode字符classes: Xan, Xps, Xsp, Xwd
- 字符中的非转义方括号 class:Oniguruma 将
[][]
视为两个空字符 classes,当 pcre 将字符 class 视为包含 ]
和 [
\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
是嵌套级别。
为了用点匹配换行符,Oniguruma 使用 m
修饰符,而 PCRE 使用 s
修饰符。
在 mb_ereg_
函数中,点默认匹配换行符。 (所以默认情况下 m
修饰符是打开的)。
PCRE 使用 s
修饰符来匹配换行符和点。 m
修饰符在 PCRE 中的行为不同,它将 ^
和 $
锚点的含义从字符串的 "start" 和 "end" 更改为 "start"和行的 "end"。
对于 Oniguruma,这些锚点的含义不会改变,它们始终匹配行的开头和结尾。为了匹配字符串的限制,它使用 \A
和 \z
也可用于 PCRE。
请注意,Oniguruma 已分叉为 Onigmo(在当前 Ruby 版本中使用)实现了更多 Perl 功能和句法元素,并且与 PCRE 更相似。
根据 PHP manual,PCRE 正则表达式的 u
修饰符为模式和主题字符串启用 UTF-8 支持。
考虑到这一点,使用带有 u
修饰符的 PCRE 表达式和相应的 mb_*
多字节字符串函数有什么区别吗? (假设所有字符串都是 UTF-8 编码。)
例如,考虑 preg_split
与 mb_split
:两者
preg_split('/' . $pattern . '/u', $string);
和
mb_split($pattern, $string);
似乎return 相同的结果。那么,应该优先选择哪一个呢?这有关系吗?
只要您严格按照 UTF-8
工作,您都可以。如果您使用另一个 charset
,那么建议使用 mb_split()
,因为 PCRE 的 u
修饰符不允许您指定 charset
,而是将字符串视为UTF-8
.
关于扩展和长期生存能力,我建议从一开始就使用 mb_split()
,以便在以后使用或需要 UTF-8
以外的东西时,您可以得到保障。
主要区别在于preg_
函数使用pcre library, when the mb_ereg_
functions (including mb_split
) use the 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)限制了 [=11 的相关性=] 功能。 (因为您需要先将字符串转换为受支持的编码,然后再将其转换回来。)
这两个正则表达式引擎或多或少具有相同的功能,但是您可以找到一些不同之处(并非详尽无遗):
Oniguruma 不支持:
- 一个字母unicode shorthand字符class要写成没有大括号。
例如:\pN
被看作pN
,你需要写:\p{N}
- unicode字符classes: Xan, Xps, Xsp, Xwd
- 字符中的非转义方括号 class:Oniguruma 将
[][]
视为两个空字符 classes,当 pcre 将字符 class 视为包含]
和[
\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
是嵌套级别。
为了用点匹配换行符,Oniguruma 使用 m
修饰符,而 PCRE 使用 s
修饰符。
在 mb_ereg_
函数中,点默认匹配换行符。 (所以默认情况下 m
修饰符是打开的)。
PCRE 使用 s
修饰符来匹配换行符和点。 m
修饰符在 PCRE 中的行为不同,它将 ^
和 $
锚点的含义从字符串的 "start" 和 "end" 更改为 "start"和行的 "end"。
对于 Oniguruma,这些锚点的含义不会改变,它们始终匹配行的开头和结尾。为了匹配字符串的限制,它使用 \A
和 \z
也可用于 PCRE。
请注意,Oniguruma 已分叉为 Onigmo(在当前 Ruby 版本中使用)实现了更多 Perl 功能和句法元素,并且与 PCRE 更相似。