Python字母数字unicode正则表达式没有按预期工作

时间:2016-11-30 13:48:20

标签: python regex python-3.x unicode

尝试编写将验证由

组成的字符串的python正则表达式
  • 任何unicode字母数字字符(包括组合字符)
  • 任意数量的空格字符
  • 任意数量的下划线
  • 任意数量的破折号
  • 任意数量的期间

我的测试字符串:

9 Melodía.de_la-montaña
9 Melodía.de_la-montaña

或使用ascii()生成的字符串文字:

str1 = '9 Melod\xeda.de_la-monta\xf1a'
str2 = '9 Melodi\u0301a.de_la-montan\u0303a'

这些看起来相同但不是,一个是标准化的,另一个使用组合字符进行变形。

这是我的第一次尝试:

import re

reg = re.compile("^[\w\.\- ]+$", re.IGNORECASE)
re.search(reg, str1) # None
re.search(reg, str2) # None

如果我删除了位置限定符并使用findall而不是search,我会得到类似['9 Melodi', 'a.de_la-montan', 'a']['9 Melod', 'a.de_la-monta', 'a']的列表。

我甚至尝试re.compile("^[\w\.\- ]+$", re.IGNORECASE | re.UNICODE)虽然在python 3中这是不必要的吗?

在搜索答案时,我发现this questionthis one以及this onethis one但是它们都很旧,处理python 2,似乎建议我写的正则表达式应该工作。 python 3.5正则表达式文档提到\w应匹配unicode但不提供涉及非ASCII文本的实际示例。

如何匹配所需的字符串?

1 个答案:

答案 0 :(得分:0)

你的第一个样本Data匹配得很好; operator=包含所有 Unicode字词字符,包括带重音符号的拉丁字符。

您可以使用unicodedata.normalize()将字符串规范化为合并后的表单,使用str1表单:

\w

请注意,不需要NFC标记,>>> import re >>> import unicodedata >>> str1 = '9 Melod\xeda.de_la-monta\xf1a' >>> str2 = '9 Melodi\u0301a.de_la-montan\u0303a' >>> reg = re.compile("^[\w\.\- ]+$") >>> reg.search(str1) <_sre.SRE_Match object; span=(0, 23), match='9 Melodía.de_la-montaña'> >>> reg.search(str2) is None True >>> reg.search(unicodedata.normalize('NFC', str2)) <_sre.SRE_Match object; span=(0, 23), match='9 Melodía.de_la-montaña'> 不关心大小写。