Python:{n}匹配的意外正则表达式行为

时间:2015-02-10 07:23:12

标签: python regex

我在http://regexpal.com/上测试了以下代码,它正确匹配了我想要的字符串。我想找到16个数字的数字,这些数字以4个块的形式出现,中间有一个空格,所以我写了以下正则表达式:

\d{4}(\s\d{4}){3}

即。匹配4个数字,然后匹配三个重复的空格集,后跟四个数字。在regexpal上,这正确匹配:

  

test1234消息 1234 5678 1234 5678

但是,在Python中,我运行以下代码:

>>> import re
>>> p = re.compile('\d{4}(\s\d{4}){3}')
>>> p.findall('test1234 message1234 5678 1234 5678')
[' 5678']
>>>

我不明白为什么它与“#56; 5678'”的第二个实例匹配?以及为什么它不像我期望的那样匹配数字块。

2 个答案:

答案 0 :(得分:3)

原始字符串是定义正则表达式的推荐方法,但这里的问题主要是因为findall方法的实现。您需要将正则表达式中存在的捕获组转换为非捕获组。因为re.findall函数给出了捕获的第一个首选项,然后是匹配项。您的正则表达式\d{4}(\s\d{4}){3}与16位数字匹配,但仅捕获最后四位加上前一空格。

p = re.compile(r'\d{4}(?:\s\d{4}){3}')

示例:

>>> import re
>>> p = re.compile(r'\d{4}(\s\d{4}){3}')
>>> p.findall('test1234 message1234 5678 1234 5678')
[' 5678']
>>> p = re.compile(r'\d{4}(?:\s\d{4}){3}')
>>> p.findall('test1234 message1234 5678 1234 5678')
['1234 5678 1234 5678']

答案 1 :(得分:-1)

您需要在字符串前面添加r或者转义反斜杠:

p = re.compile(r'\d{4}(\s\d{4}){3}')

p = re.compile('\\d{4}(\\s\\d{4}){3}')