尝试编写将验证由
组成的字符串的python正则表达式我的测试字符串:
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 question和this one以及this one和this one但是它们都很旧,处理python 2,似乎建议我写的正则表达式应该工作。 python 3.5正则表达式文档提到\w
应匹配unicode但不提供涉及非ASCII文本的实际示例。
如何匹配所需的字符串?
答案 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'>
不关心大小写。