在Python中匹配备用regexp

时间:2012-03-20 20:02:50

标签: python regex

我正在使用Python来解析文件以搜索电子邮件地址,但我无法弄清楚备用正则表达式的语法应该是什么。这是代码:

addresses = []

pattern = '(\w+)@(\w+\.com)|(\w+)@(it.\w+\.com)'
for line in file:
    matches = re.findall(pattern,line)
    for m in matches:
        address = '%s@%s' % m
        addresses.append(address)

所以我想查找看起来像john@company.com或john@it.company.com的地址,但上面的代码不起作用,因为前两组是空的或后两组是空的。什么是正确的解决方案?我需要使用组来分别存储用户名(在@之前)和服务器名称(在@之后)。

编辑:匹配的电子邮件地址只是一个例子。我想要找出的是如何匹配只有一个共同点的不同正则表达式 - 它们匹配两个组。

2 个答案:

答案 0 :(得分:2)

(\w+)@((?:it\.)?\w+\.com)

您希望在@之后捕获该部分,无论它是example.com还是it.example.com,因此您将两个选项都放在同一个捕获组中。但由于它们共享相似的格式,因此您可以将(it\.\w+\.com|\w+\.com)压缩为((it\.)?\w+\.com)

(?: )使该parens成为非捕获组,因此它不会参与您的匹配组。第一个(\w+)将匹配一个匹配,((?:it\.)?\w+\.com)之后的整个@将匹配一个匹配。这是两个匹配总数,加上完整字符串的默认组-0匹配。

编辑:要回答你的新问题,你所要做的就是按照我使用的分组,但在你压缩它之前停止。 如果您的测试用例是:

1)example@abcdef

2)example@123456

你可以这样编写你的正则表达式:(\w+)@([a-zA-Z]+|\d+),它总是在组1中@之前的部分,以及组2之后的部分。注意只有两对parens,|(“或”)运算符出现在第二个parens组内。

答案 1 :(得分:2)

我曾经发现here写得很好的电子邮件正则表达式,它是用于从通用字符串中提取各种有效的电子邮件地址的构建,所以它也应该能够做你想要的。< / p>

示例:

>>> email_regex = re.compile("""((([a-zA-Z0-9!\#\$%&'*+\-\/=?^_`{|}~]+|"([a-zA-Z0-9!\#\$%&'*+\-\/=?^_`{|}~(),:;<>@\[\]\.]|\\[ \\"])*")\.)*([a-zA-Z0-9!\#\$%&'*+\-\/=?^_`{|}~]+|"([a-zA-Z0-9!\#\$%&'*+\-\/=?^_`{|}~(),:;<>@\[\]\.]|\\[ \\"])*"))@((([a-zA-Z0-9]([a-zA-Z0-9]*(\-[a-zA-Z0-9]*)*)?\.)*[a-zA-Z]+|\[((0?\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\.){3}(0?\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])\]|\[[Ii][Pp][vV]6(:[0-9a-fA-F]{0,4}){6}\]))""")
>>>
>>> m = email_regex.search('john@it.company.com')
>>> m.group(0)
'john@it.company.com'
>>> m.group(1)
'john'
>>> m.group(7)
'it.company.com'
>>>
>>> n = email_regex.search('john@company.com')
>>> n.group(0)
'john@company.com'
>>> n.group(1)
'john'
>>> n.group(7)
'company.com'