2016-05-08 234 views
2

我在python中做了一个非常简单的正则表达式,并且在使用“或”运算符时看到一些奇怪的行为。Python中的正则表达式匹配

我试图解析如下:

>> str = "blah [in brackets] stuff" 

,使其返回:

>> ['blah', 'in brackets', 'stuff'] 

要匹配括号内的文字,我使用的外观后面,向前看,即:

>> '(?<=\[).*?(?=\])' 

如果单独使用,确实可以捕获括号中的文字:

>> re.findall('(?<=\[).*?(?=\])' , str) 
>> ['in brackets'] 

但是,当我结合或运营商来解析空间之间的字符串,支架匹配某种方式分解:

>> [x for x in re.findall('(?<=\[).*?(?=\])|.*?[, ]' , str) if x!=' ' ] 
>> ['blah', '[in ', 'brackets] '] 

对我的生活中,我无法理解这种行为。任何帮助,将不胜感激。

谢谢!

+1

这可能帮助 - https://regex101.com/r/xM7sK0/1 - 左边你可以进入调试器在那里将说明如何它匹配了它所做的事情。 – TessellatingHeckler

+0

谢谢,这真的很有用。 – FrancisWolcott

+0

问题是正则表达式的后半部分也与括号相匹配。第一场比赛后(“blah”),剩余的文字是[括号内]。正则表达式的前半部分在这里不匹配,因为向后看不到左括号。所以正则表达式的后半部分再次匹配并找到文本“[in”。 –

回答

2

你可以这样做:

>>> s = "blah [in brackets] stuff" 

>>> re.findall(r'\b\w+\s*\w+\b', s) 
['blah', 'in brackets', 'stuff'] 
+0

谢谢!这是一个很好的解决方案。我仍然有兴趣了解为什么我的工作无法正常进行......在我的脑海中逐步完成它是有道理的:尝试匹配括号中的内容,如果不匹配,则匹配前面有空格的内容。对于我来说,or或者操作符的引入会打破括号匹配。有任何想法吗? – FrancisWolcott

0

如果你正在寻找一种简单的方法来做到这一点,然后用这个。 注:我用str替换了str,因为'str'是python的一个内置函数。

import re 
string = "blah [in brackets] stuff" 
f = re.findall(r'\w+\w', string) 
print(f) 

输出:[“括号”嗒嗒',“东西”]

0

答案为止没有考虑到,你可能有括号内超过2个字帐户,甚至一个字。以下正则表达式将分割在括号和括号中的任何前导或尾随空格上。如果字符串中有更多的括号内容,它也会工作。

s = "blah [in brackets] stuff" 

s = re.split(r'\s*\[|\]\s*', s) # note the 'or' operator is used and literal opening and closing brackets '\[' and '\]' 

print(s) 

输出:['blah', 'in brackets', 'stuff']

以及使用与不同量的括号内词语的字符串并且使用几组括号的一个示例:

s = "blah [in brackets] stuff [three words here] more stuff [one-word] stuff [a digit 1!] stuff." 

s = re.split(r'\s*\[|\]\s*', s) 

print (s) 

输出:['blah', 'in brackets', 'stuff', 'three words here', 'more stuff', 'one-word', 'stuff', 'a digit 1!', 'stuff.']

+0

我真的很喜欢你的解决方案。将其他分隔符与括号放在一组中也很容易。但唯一的一点是,它不会将多个单词分割为括号外的多个单词,即它会返回“更多内容”而不是['more','stuff']。 – FrancisWolcott

2

对于那些有兴趣的,这是我最终成功的正则表达式。有可能是一个更优雅的解决方案的地方,但这个工程:

>>> s = "blah 2.0 stuff 1 1 0 [in brackets] more stuff [1]" 

>>> brackets_re = '(?<=\[).*?(?=\])' 
>>> space_re = '[-\.\w]+(?=)' 
>>> my_re = brackets_re + '|' + space_re 

>>> re.findall(my_re, s) 
['blah', '2.0', 'stuff', '1', '1', '0', 'in brackets', 'more', 'stuff', '1'] 
+0

弗朗西斯做得很好 –