Perl 和其他一些当前的正则表达式引擎在正则表达式中支持 Unicode 属性,例如类别。例如,在 Perl 中,您可以使用\p{Ll}
匹配任意小写字母或p{Zs}
任何空格分隔符。我在 Python 的 2.x 和 3.x 行中都没有看到对此的支持(很遗憾)。有人知道获得类似效果的好策略吗?欢迎使用本土解决方案。
6 回答
正则表达式模块(标准模块的替代方案re
)支持 Unicode 代码点属性和\p{}
语法。
Have you tried Ponyguruma, a Python binding to the Oniguruma regular expression engine? In that engine you can simply say \p{Armenian}
to match Armenian characters. \p{Ll}
or \p{Zs}
work too.
您可以在每个字符上煞费苦心地使用 unicodedata:
import unicodedata
def strip_accents(x):
return u''.join(c for c in unicodedata.normalize('NFD', x) if unicodedata.category(c) != 'Mn')
说到本土解决方案,前段时间我写了一个小程序来做到这一点 - 将写入的 unicode 类别转换\p{...}
为一系列值,从 unicode规范(v.5.0.0) 中提取。仅支持类别(例如:L
、、Zs
),并且仅限于 BMP。我把它贴在这里,以防有人觉得它有用(尽管 Oniguruma 似乎确实是一个更好的选择)。
示例用法:
>>> from unicode_hack import regex
>>> pattern = regex(r'^\\p{Lu}(\\p{L}|\\p{N}|_)*')
>>> print pattern.match(u'疂_1+2').group(0)
疂_1
>>>
这是来源。还有一个JavaScript 版本,使用相同的数据。
请注意,while\p{Ll}
在 Python 正则表达式中没有等效项,\p{Zs}
应包含在'(?u)\s'
. 正如(?u)
文档所说,“使 \w、\W、\b、\B、\d、\D、\s 和 \S 依赖于 Unicode 字符属性数据库。” 并且\s
表示任何间距字符。
没错,Python 正则表达式解析器不支持 Unicode 属性类。
如果你想做一个很好的 hack,这通常会很有用,你可以创建一个预处理器来扫描字符串以查找此类标记(\p{M}
或其他)并将它们替换为相应的字符集,例如,\p{M}
将变为[\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]
,并且\P{M}
会变成[^\u0300–\u036F\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F]
.
人们会感谢你的。:)