如何在同一行中分隔多个正则表达式匹配

时间:2013-05-18 01:28:47

标签: python regex regex-group

我正在尝试使用正则表达式来解析以(key###value)格式编写的值。该值始终为数字。无论如何,我认为用python做它最简单,所以这里有一些我正在尝试的代码:

import re

line = "(text 1###123)(text 2###345)";

matchObj = re.match( r'\(.*###[0-9]+\)', line)

if matchObj:
   print matchObj.group(0) # produces (text 1###123)(text 2###345)
   # print matchObj.group(1) # gives an error
else:
   print "No match!!"

即使有两个与我写的正则表达式匹配的不同对象,python将它们作为单个字符串返回给我 - 不是我想要的。我该如何解决这个问题?

事实上,我真正想要的是将字符串分成["text 1", "123", "text 2", "345]之类的东西。因此,如果有人有一个简单的方法来实现这一点,我也非常感谢。

2 个答案:

答案 0 :(得分:4)

你没有正确的正则表达式,你需要有捕获组。你的例子有parens逃脱。这是您实际需要的正则表达式。 ?之后的*使其非贪婪(以便在匹配时尝试尽可能少的字符)。

\((.*?)###([0-9]+)\)

您当前的正则表达式只有转义的parens,因此您实际上没有任何捕获组。要获得所有匹配项,您需要使用re.findall。但是如果你需要使用两个捕获组,这将产生如下:

regex = r'\((.*?)###([0-9]+)\)'
re.findall(regex, "(text 1###123)(text 2###345)") # [("text 1", "123"), ("text 2", "345")]

如果你想要压扁它,这也很简单。

答案 1 :(得分:1)

在这个问题中,有几点正在发挥作用。

  1. 首先是re.match()所做的。这个函数实际上希望能够在字符串的开头处开始匹配,在这种情况下它不能,因为你在那里有一个左括号。因此,您需要查看re.search(),更有可能查看re.findall()函数。
  2. 此外,您不需要像在其他语言中那样在Python中转义组。
  3. 您可能不想使用.*,因为这往往是贪婪的。虽然您可以使用.*?,但通常最好花些时间为正则表达式进行更具体的搜索。
  4. 总之,我建议如下:

    matchObj = re.findall(r'(([\w\d ]+)###(\d+))', line)
    

    这将导致一个易于排序的数组:

    >>> matchObj
    [('text 1###123', 'text 1', '123'), ('text 2###345', 'text 2', '345')]
    >>> matchObj[0]
    ('text 1###123', 'text 1', '123')