在Python中特别小心非ASCII
Python如何处理模式和字符串中的非ASCII或未能处理非ASCII时,确实存在一些细微的问题。更糟糕的是,这些差异不仅取决于您使用的是哪个版本的Python,还取决于您是否拥有“广泛的构建”。
通常,当您处理Unipre时, 构建较宽的Python 3效果最佳, 而构建较窄的Python 2效果最差,但与Perl正则表达式 相对于
Unipre的工作方式相比,所有组合仍然相差甚远。如果要在Python中查找ᴘᴄʀᴇ模式,则可能需要比其旧
re模块更进一步。
只要您使用足够高级的Python版本,就可以 彻底
解决所有令人烦恼的“广泛构建”问题。这是v3.3发行说明的摘录:
功能性
PEP 393引入的更改如下:
- Python现在始终支持所有Unipre代码点,包括非BMP代码点(即,从U + 0000到U +
10FFFF)。窄和宽版本之间的区别不再存在,并且即使在Windows下,Python现在也像宽版本一样。- 随着狭窄版本的终止,狭窄版本所特有的问题也已修复,例如:
len()现在对于非BMP字符始终返回1,因此len('U0010FFFF') == 1;- 代理对不会在字符串文字中重组,因此
'uDBFFuDFFF' != 'U0010FFFF';;- 索引或切片非BMP字符将返回期望值,因此
'U0010FFFF'[0]现在返回,'U0010FFFF'而不是'uDBFF';- 现在,标准库中的所有其他函数都可以正确处理非BMP代码点。
*现在的值sys.maxunipre始终为1114111(十六进制为0x10FFFF)。PyUnipre_GetMax()为了向后兼容,该函数仍返回0xFFFF或0x10FFFF,并且不应与新的Unipre
API一起使用(请参见问题13054)。 The ./configure标志--with-wide-unipre已被删除。
Python正则表达式的未来
与标准Python发行版
re库中当前可用的库相比,Matthew Barnett的
regex同时适用于Python 2和Python
3的模块在几乎所有可能的方式上都好得多,并且会
re最终被替换。与您的问题特别相关的是,他的
regex库在各个方面都比现在更加强大(
即与 Perl兼容
得多
re),这将使您更容易将Perl正则表达式移植到Python。因为它是完全重写(例如,从头开始,而不是在汉堡包中),所以它是在考虑非ASCII的情况下写的,而
re不是这样。
regex因此,该库在如何处理事物方面更严格地遵循UTS#18(Unipre正则表达式)的(当前)建议。它在大多数情况下(即使不是全部)都
达到或超过了UTS#18 Level 1的要求 ,这通常是您必须使用ICU
regex库或Perl本身的东西–或者,如果您特别有胆量,则对它的正则表达式进行新的Java
7更新,例如也符合UTS#18的一级要求。
除了满足那些对基本Unipre支持绝对是必不可少的,但
Python当前re
库不能
regex满足的第一级要求之外
,
该强大的库还满足了RL2.5命名字符(
N{...})),RL2.2扩展字素的第二级要求。集群(X),以及来自UTS#18修订版14的新的RL2.7,关于完全属性。
Matthew的
regex模块还进行Unipre大小写折叠,因此区分大小写的匹配在Unipre上可靠地起作用, 而 Unipre
则不然。
re
以下不再是正确的,因为
regex现在支持完整的Unipre大小写折叠,例如Perl和Ruby。
一个非常小的区别是,目前,Perl的不区分大小写的模式使用完整的面向字符串的大小写折叠,而他的regex模块仍使用简单的面向单个字符的大小写折叠,但这是他正在研究的问题。这实际上是一个非常棘手的问题,除了Perl之外,甚至只有Ruby都会尝试。
下充分casefolding,这意味着(例如)
"ß"现在是正确的匹配
"SS",
"ss",
"ſſ",
"ſs"(等)当选择不区分大小写匹配。(这在希腊语中比在拉丁语中更重要。)
另请参阅我第三次OSCON2011演讲中的幻灯片或doc源代码,标题为
_“ Unipre支持大战:好,坏和(主要是)丑陋
”,_以获取有关Javascript,PHP,Go,Ruby,Python,Java的Unipre支持的一般问题。和Perl。如果不能使用Perl正则表达式或ICU正则表达式库(可惜没有命名捕获),那么Matthew的
regexPython可能就是您的最佳选择。
NᴏᴛᴀBᴇɴᴇs.ᴠ.ᴘ。(= s’il vousplaît等) :Python库的作者实际上 并未
在下面放置未经请求的非商业性非广告
regex。:)
酷regex
功能
Python
regex库具有 超精巧的功能
,其中一些在其他正则表达式系统中找不到。无论您是偶然使用它来获得它的坚固性还是出色的Unipre支持,这些都非常值得一试。
该模块感兴趣的一些杰出功能包括:
- 可变宽度向后看 ,这是一个功能,在正则表达式引擎中很少见,并且在您真正想要它时非常沮丧。这很可能是正则表达式中最常请求的功能。
- 向后搜索,因此您不必自己先反转字符串。
- 作用域
ismx
类型选项,以便(?i:foo)
仅对foo进行大小写折叠,而不对整个字体进行折叠,或者(?-i:foo)
仅对foo对其进行关闭。这就是Perl(或可以)的工作方式。 - 基于编辑距离模糊匹配(这迪·曼伯的
agrep
和glimpse
也有) - 通过
L<list>
插值隐式最短到最长排序的命名列表 - 元字符只有一个单词的开始或仅结束特别地匹配,而不是任一侧(
m
,M
) - 所有Unipre行分隔符支持(Java可以做到这一点,如Perl中尽管有几分勉强
R
每RL1.6。 - 根据RL1.3在括号中的字符类上进行全套运算(并集,交集,差和对称差),这比在Perl中轻松进行得多。
- 允许重复捕获组,例如
(w+s+)+
您可以在其中获得第一个组的所有单独匹配,而不仅仅是最后一个匹配。(我相信C#也可以这样做。) - 与前行中的偷偷摸摸的捕获组相比,这是一种更为直接的重叠比赛方式。
- 所有组的开始和结束位置,以便以后进行切片/子字符串操作,这与Perl
@+
和@-
数组非常相似。 - 分支重置操作符通过
(?|...|...|...|)
其在Perl中的工作方式重置每个分支中的组编号。 - 可以配置为让咖啡在早上等您。
- 支持RL2.3中更复杂的单词边界。
- 默认情况下,假设Unipre字符串,并完全支持RL1.2a让
w
,b
,s
,而这些工作对Unipre的。 - 支持字素
X
。 - 支持
G
连续点声明。 - 对于64位版本(
re
仅具有32位索引)可以正常工作。 - 支持多线程。
好的,这已经足够炒作了。:)
另一个优良的替代正则表达式引擎
如果您是正则表达式怪胎,那么值得一看的最后一个替代方法是将Python库绑定到Russ
Cox出色的RE2库。它还本地支持Unipre,包括简单的基于字符的大小写折叠,并且与之不同的
re是,它同时提供了Unipre常规类别和Unipre脚本字符属性,这是更简单的Unipre处理最常需要的两个关键属性。
尽管RE2错过了一些Unipre特性,例如
N{...}ICU,Perl和Python中的命名字符支持,但是RE2具有非常重要的计算优势,当您担心基于饥饿的拒绝服务时,它便成为了正则表达式引擎的首选
通过Web查询等中的正则表达式进行攻击。它通过禁止反向引用来管理此问题,这会导致正则表达式停止正常运行,并有可能在时间和空间上发生超指数爆炸。
RE2的库绑定不仅适用于C / C ++和Python,还适用于Perl,尤其是Go(适用于Go),后者打算很快替换那里的标准正则表达式库。



