Python正则expression式匹配Unicode属性

Perl和其他一些当前的regex引擎在正则expression式中支持Unicode属性,例如类别。 例如在Perl中,可以使用\p{Ll}来匹配任意小写字母,或者使用p{Zs}来匹配任何空格分隔符。 我在Python的2.x和3.x行中没有看到对此的支持(带来的遗憾)。 有没有人知道获得类似效果的好策略? 欢迎使用本土解决scheme。

你有没有尝试Ponyguruma ,一个绑定到Oniguruma正则expression式引擎的Python? 在那个引擎中,你可以简单地说\p{Armenian}来匹配亚美尼亚字符。 \p{Ll}\p{Zs}也可以。

正则expression式模块(替代标准re模块)使用\p{}语法支持Unicode码点属性。

你可以在每个字符上刻意使用unicodedata:

 import unicodedata def strip_accents(x): return u''.join(c for c in unicodedata.normalize('NFD', x) if unicodedata.category(c) != 'Mn') 

说到本土解决scheme,前一段时间我写了一个小程序来做这件事 – 将一个unicode类别写成\p{...}到unicode 规范 (v.5.0.0)中提取的一个值范围内。 只支持类别(例如: LZs ),并且仅限于BMP。 我把它张贴在这里,以防有人觉得有用(虽然那Oniguruma真的似乎是一个更好的select)。

用法示例:

 >>> from unicode_hack import regex >>> pattern = regex(r'^\\p{Lu}(\\p{L}|\\p{N}|_)*') >>> print pattern.match(u'疂_1+2').group(0) 疂_1 >>> 

这是来源 。 还有一个JavaScript版本 ,使用相同的数据。

你说得对,Unicode属性类不被Python正则expression式parsing器支持。

如果你想做一个很好的黑客攻击,这通常是有用的,你可以创build一个预处理器,扫描一个string为这样的类标记( \p{M}或其他),并用相应的字符集replace它们,例如, \p{M}将会变成[\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]\P{M}会变成[^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]

人们会感谢你。 🙂

请注意,虽然\p{Ll}在Python正则expression式中没有等价物, \p{Zs}应该由'(?u)\s'覆盖。 (?u) ,正如文档所说:“使\ w,\ w,\ b,\ b,\ d,\ D,\ s和\ S依赖于Unicode字符属性数据库”和\s表示任何间距字符。