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)中提取的一个值范围内。 只支持类别(例如: L
, Zs
),并且仅限于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
表示任何间距字符。