Python中的正则表达式。有人能帮助新手吗?

Python中的正则表达式。有人能帮助新手吗?,python,regex,Python,Regex,这个简单的问题困扰着我。我之前发布了一些关于试图清理地址数据库的信息,有人建议GeoPy检查地址的有效性。我不知道这是一个很棒的工具,但在做这件事之前,我需要清理一下数据库,因为geopy不会处理混乱的格式。 解决方案是使用正则表达式,我想对于我在数据库中看到的大多数类型的地址,我都已经修复了正则表达式。 然而,我对我定义的最后一个RegExp(代码中称为r4)有问题,因为它正在重新调整第一个括号中我不需要的部分,我不知道为什么在它返回最后一个组(城市:伦敦,国家:英格兰)时会有额外的空格。 有

这个简单的问题困扰着我。我之前发布了一些关于试图清理地址数据库的信息,有人建议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"
  • 如果处于循环中,则re.compile会加快速度
  • 大型正则表达式非常高效
  • 一个小组记录可以告诉你在哪里找到了东西
  • #


    您的主要问题是
    \(
    在您的捕获组中。如果您不想将其包括在捕获组中,但仍想使用它进行匹配,请将其放在正则表达式的括号外。此外,评估所有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}]