2013-01-06 32 views
7

我使用Python Regex遇到了一个小问题。使用交替运算符匹配多个正则表达式模式?

想这是输入:

(zyx)bc 

我想要实现的是获得什么是括号之间的一个匹配,内外任何字符作为一个单独的比赛。期望的结果将沿着以下方向:

['zyx','b','c'] 

应该保持匹配的顺序。

我试着用Python 3.3获得这个,但似乎无法弄清楚正确的正则表达式。到目前为止,我有:

matches = findall(r'\((.*?)\)|\w', '(zyx)bc') 

print(matches)产生如下:

['zyx','',''] 

任何想法我做错了吗?

+0

为什么不只是'某某| A | B'? – fge

+0

这只是一个示例输入。正则表达式应该能够区分不同的情况,例如(ab)(bc)(ca),abc,(abc)(abc)(abc)或(zyx)bc等,同时识别哪些字符在括号,而不是。 –

回答

11

re.findall文档:

如果一个或多个基团存在于该图案,返回组的列表;如果模式有多个组,这将是一个元组列表。

虽然您的正则表达式匹配字符串三次,但(.*?)组在第二场比赛中为空。如果你想在正则表达式的另一半的输出,你可以添加第二个组:

>>> re.findall(r'\((.*?)\)|(\w)', '(zyx)bc') 
[('zyx', ''), ('', 'b'), ('', 'c')] 

或者,你可以删除所有群体重新获得一个简单的字符串列表:

>>> re.findall(r'\(.*?\)|\w', '(zyx)bc') 
['(zyx)', 'b', 'c'] 

您需要手动删除括号。

+0

供参考:谢谢你的答案。要删除括号:'match = [match.strip('()')用于匹配findall(r'\(。*?\)| \ w',case)]' –

1

的文档提到专门治疗小组,所以不要把一组围绕括号的模式,你会得到一切,但你需要从匹配的数据自己删除的括号:

>>> re.findall(r'\(.+?\)|\w', '(zyx)bc') 
['(zyx)', 'b', 'c'] 

或使用更多的组,然后处理由此产生的元组,让你寻求字符串:

>>> [''.join(t) for t in re.findall(r'\((.+?)\)|(\w)', '(zyx)bc')] 
>>> ['zyx', 'b', 'c'] 
1
In [108]: strs="(zyx)bc" 

In [109]: re.findall(r"\(\w+\)|\w",strs) 
Out[109]: ['(zyx)', 'b', 'c'] 

In [110]: [x.strip("()") for x in re.findall(r"\(\w+\)|\w",strs)] 
Out[110]: ['zyx', 'b', 'c'] 
2

让我们使用re.DEBUG看看我们的输出。

branch 
    literal 40 
    subpattern 1 
    min_repeat 0 65535 
     any None 
    literal 41 
or 
    in 
    category category_word 

哎哟,只有一个subpattern在那里,但如果存在re.findall只翻出subpattern小号!

a = re.findall(r'\((.*?)\)|(.)', '(zyx)bc',re.DEBUG); a 
[('zyx', ''), ('', 'b'), ('', 'c')] 
branch 
    literal 40 
    subpattern 1 
    min_repeat 0 65535 
     any None 
    literal 41 
or 
    subpattern 2 
    any None 

更好。 :)

现在我们只需要将其制作为您想要的格式即可。

[i[0] if i[0] != '' else i[1] for i in a] 
['zyx', 'b', 'c'] 
1

其他答案已告诉你如何得到你需要的结果,但用额外的步骤手动删除括号。如果您在您的正则表达式使用lookarounds,你会不会需要手动剥离括号:

>>> import re 
>>> s = '(zyx)bc' 
>>> print (re.findall(r'(?<=\()\w+(?=\))|\w', s)) 
['zyx', 'b', 'c'] 

解释:

(?<=\() // lookbehind for left parenthesis 
\w+  // all characters until: 
(?=\)) // lookahead for right parenthesis 
|  // OR 
\w  // any character