在匹配电子邮件地址时,在匹配yasar@webmail之类的东西之后,我想捕获一个或多个(\.\w+)(我做的事情有点复杂,这只是一个例子),我尝试添加(。\ w +)+ ,但仅捕获最后一场比赛。例如,yasar@webmail.something.edu.tr匹配,但在.tr部分之后仅包含yasar@webmail,因此我丢失了.something.edu组。我可以在Python正则表达式中执行此操作,还是建议您先匹配所有内容,然后再拆分子模式?

评论

捕获重复表达式是在Python Issue 7132中提出的,但被拒绝了。但是,第三方正则表达式模块支持它。

@ToddOwen但是,现在在2.7中不可行吗?我不知道什么时候有可能。但是,在2.7中使用re模块从stackoverflow.com/a/9765037/3541976中获得的答案似乎对我来说还不错。

@MichaelOhlrogge问题7132是关于如果捕获括号位于重复中会发生什么情况。该问题尚未解决,仍将仅保留最后一场比赛。如您所链接的答案中所述,一种可能的解决方法是将捕获括号放在重复的模式周围。 (请注意,(?:...)不包含括号)。

@ToddOwen知道了,谢谢,这是一个有用的说明!

#1 楼

re模块不支持重复捕获(regex支持它):

>>> m = regex.match(r'([.\w]+)@((\w+)(\.\w+)+)', 'yasar@webmail.something.edu.tr')
>>> m.groups()
('yasar', 'webmail.something.edu.tr', 'webmail', '.tr')
>>> m.captures(4)
['.something', '.edu', '.tr']


在您的情况下,我将在以后拆分重复的子模式。它导致了一个简单易读的代码,例如,请参阅@ Li-aung Yip的答案中的代码。

评论


出于好奇,当您匹配重复的捕获时,如何编写替换模式? \ 1,\ 2,\ 3等的含义是否会根据您匹配的次数(\。\ w +)而改变?

–叶立昂
2012年3月19日在7:55

@ Li-aung Yip:\ 1对应于m.group(1);含义没有改变。您可以使用函数作为替换模式,并在其中调用m.captures()。

– jfs
2012年3月19日在9:03

在您的示例中,\ 1,\ 2和\ 3的含义很明显,因为它们仅捕获一次。但是\ 4对应(\。\ w +)+的含义是什么? \ 4似乎是“第四捕获组匹配的最后一个子字符串”,在这种情况下为.tr。

–叶立昂
2012年3月19日在9:12

@ Li-aung Yip:上面的m.groups()明确显示\ 4是什么。

– jfs
2012年3月19日在9:13

含义没有改变:\ 4等于m.group(4)。

– jfs
2012年3月19日在9:21

#2 楼

这将起作用:更好的方法是:

>>> regexp = r"[\w\.]+@(\w+)(\.\w+)?(\.\w+)?(\.\w+)?(\.\w+)?(\.\w+)?"
>>> email_address = "william.adama@galactica.caprica.fleet.mil"
>>> m = re.match(regexp, email_address)
>>> m.groups()
('galactica', '.caprica', '.fleet', '.mil', None, None)


请注意,只要电子邮件地址简单,则正则表达式就可以了-但是有很多事情要做争取。有关电子邮件地址正则表达式的详细处理,请参阅此问题。

#3 楼

您可以通过执行以下操作来解决(\.\w+)+仅捕获最后一个匹配项的问题:((?:\.\w+)+)

评论


对于缩写(如果是小写的话):re.sub(ur'((?:[az] \。){2,})',lambda m:m.group(1).replace('。' ,''),文字)

–scharfmn
15年8月15日在9:58

谢谢。我能够加上括号使我能够匹配重复的子模式,但是匹配中有一个组与该模式的最后一个模式匹配。我没有看到(?:...)成为一个不吸引人的团体。 docs.python.org/2/library/re.html#regular-expression-syntax添加可解决该问题。

– Tim Swast
16年7月21日在22:22

谢谢@TimSwast,这正是我需要的评论和参考!

– Michael Ohlrogge
18年11月24日在18:00

#4 楼

这就是您要寻找的东西:

>>> import re

>>> s="yasar@webmail.something.edu.tr"
>>> r=re.compile("\.\w+")
>>> m=r.findall(s)

>>> m
['.something', '.edu', '.tr']


评论


这与yasar @ webmail不匹配。因此,如果电子邮件地址以外的其他内容有多个分隔符,则很容易获得误报结果。

– Michael Ohlrogge
18年11月24日在18:07

OP清楚地写到,这只是一个例子,他想做的事情更加复杂。因此,我的答案。

–图萨·瓦兹拉尼(Tushar Vazirani)
18年11月24日在18:09

是的,但是问题是您的解决方案即使在OP给出的问题的简化版本中也无法使用。即使对RegEx有最基本的了解,您的解决方案也非常简单。所有其他答案都更加复杂,因为这是一个真正不平凡的问题。

– Michael Ohlrogge
18年11月24日在18:31