Python中的正则表达式。有人能帮助新手吗?
这个简单的问题困扰着我。我之前发布了一些关于试图清理地址数据库的信息,有人建议GeoPy检查地址的有效性。我不知道这是一个很棒的工具,但在做这件事之前,我需要清理一下数据库,因为geopy不会处理混乱的格式。 解决方案是使用正则表达式,我想对于我在数据库中看到的大多数类型的地址,我都已经修复了正则表达式。 然而,我对我定义的最后一个RegExp(代码中称为r4)有问题,因为它正在重新调整第一个括号中我不需要的部分,我不知道为什么在它返回最后一个组(城市:伦敦,国家:英格兰)时会有额外的空格。 有人能帮忙吗Python中的正则表达式。有人能帮助新手吗?,python,regex,Python,Regex,这个简单的问题困扰着我。我之前发布了一些关于试图清理地址数据库的信息,有人建议GeoPy检查地址的有效性。我不知道这是一个很棒的工具,但在做这件事之前,我需要清理一下数据库,因为geopy不会处理混乱的格式。 解决方案是使用正则表达式,我想对于我在数据库中看到的大多数类型的地址,我都已经修复了正则表达式。 然而,我对我定义的最后一个RegExp(代码中称为r4)有问题,因为它正在重新调整第一个括号中我不需要的部分,我不知道为什么在它返回最后一个组(城市:伦敦,国家:英格兰)时会有额外的空格。 有
import re
r1 = '\s*ForeignZip.*--\s*([\d\.]+)'
r2 = '(\w+)\W*,\W*(\w*)'
r3 = '(?<=\().*?(?=\))'
r4 = '(\w+\W\()'
Location = [' ForeignZip (xxx) -- 734.450','Washington, DC.','London (England)']
for item in Location:
print item
match1 = re.search(r1,item)
match2 = re.search(r2,item)
match3 = re.search(r3,item)
match4 = re.search(r4,item)
if match1:
print 'pattern 1 found:', match1.group(1)
elif match2:
print 'pattern 2 found: City :' + match2.group(1) + ", State :" + match2.group(2)
elif match3:
print 'pattern 3 found: City: ', match4.group() + ", Country :" + match3.group(0)
else:
print 'no match'
让我们看看这个:
(\w+\W\()
首先,您正在保存一个引用,其中最外层的paren指向与它们内部匹配的任何对象,因此:
\w+\W\(
…请注意\(
-它与文本打开参数匹配
另外,我不是Python高手,但这里的逗号是不是碰巧应该是加号
City: ', match4.group() + ...
它返回括号,因为它是模式的一部分:
\(
您可以这样做:
r4 = '(\w+\W)\('
[...]
print 'pattern 3 found: City: ', match4.group(1)
将r4更改为以下内容
r4 = '\w+\W'
也在,
elif match3:
print 'pattern 3 found: City: ', match4.group() + ", Country :" + match3.group(0)
你在城市后面放了一个“,”而不是放空格的“+”。把它改成如下
elif match3:
print 'pattern 3 found: City: ' + match4.group() + ", Country :" + match3.group(0)
只需对以后的正则表达式进行一点更改是必要的……可能有一百万种方法可以做到这一点,但这里有一种:
r3 = r'(\w+)\s+\((\w+)\)' #Match a word (group1), whitespace followed by a '(' then another word (group2) and finally a closing ')'
或者使空白完全不重要:
r3 = r'(\s*(?:\w+\s*)*)\s*\(\s*((?:\w+\s*)+)\s*\)'
它基本上是以前的正则表达式,只是它将\w+
替换为(?:\w+\s*)*
,它允许多个单词匹配,但不捕获它们——它使“组”保持不变,因为(?:…)
从不将匹配的字符串保存到任何地方
现在将第三个测试更改为:
elif match3:
print 'pattern 3 found: City : '+ match3.group(1) + ", Country :" + match3.group(2)
我还删除了r4,因为不再需要它了…(为了保持一致性,我还将“,”改为“+”,并在“城市:”中添加了一个空格)
还请注意,在处理正则表达式时,使用“原始”字符串通常很好(这可以防止python损坏字符串中的标记。要测试差异,请尝试:
print ("\n") #prints newline
print (r"\n") #prints "\n"
您的主要问题是
\(
在您的捕获组中。如果您不想将其包括在捕获组中,但仍想使用它进行匹配,请将其放在正则表达式的括号外。此外,评估所有4种模式的效率也很低。为什么不在运行每个正则表达式后检查是否找到匹配项,这样,如果您找到了与第一个pa的匹配项泰伦,你可以避免评估所有其他模式。太好了!!谢谢你的反馈!当然,没问题。一定要看到另一个答案…它们解释了你表现得非常好的行为(特别是为什么你有一个尾随括号)。我只是用我的方式写我的答案,因为使用2个“R”似乎是一种浪费(使用lookahead和lookahead--yuck)太复杂了,因为只有一个re(没有lookahead/behind)。谢谢!我没有注意到“,”。反馈太好了!非常好的解决方案。此模板将在我的项目的其他部分帮助我很多。谢谢。干杯!
print ("\n") #prints newline
print (r"\n") #prints "\n"
finder = re.compile('\s*ForeignZip.*--\s*(?P<fzip>[\d\.]+)|(?P<uscity>\w+)\W*,\W*(?P<state>\w*)|(?P<fcity>\w+)\W*\((?P<country>\w*)\)')
[finder.match(l).groupdict() for l in ll]
[{'country': None,
'fcity': None,
'fzip': '734.450',
'state': None,
'uscity': None},
{'country': None,
'fcity': None,
'fzip': None,
'state': 'DC',
'uscity': 'Washington'},
{'country': 'England',
'fcity': 'London',
'fzip': None,
'state': None,
'uscity': None}]