我正试图用正则表达式抓住括号外的任何文本。
示例字符串
Josie Smith [3996 COLLEGE AVENUE,SOMETOWN,MD 21003] Mugsy Dog Smith [2560 OAK ST,GLENMEADE,WI 14098]
我可以通过以下方式成功地在方括号内获取文本
addrs = re.findall(r"\[(.*?)\]", example_str)
print addrs
[u'3996 COLLEGE AVENUE, SOMETOWN, MD 21003',u'2560 OAK ST, GLENMEADE, WI 14098']
但是我无法在方括号外面 。我尝试过以下内容:
names = re.findall(r"(.*?)\[.*\]+", example_str)
但只能找到名字:
print names
[u'Josie Smith ']
到目前为止,我只看到一个包含一到两个name [address]
组合的字符串,但我假设字符串中可以有任意数量的字符串。
答案 0 :(得分:9)
如果没有嵌套括号,您可以这样做:
re.findall(r'(.*?)\[.*?\]', example_str)
但是,你甚至不需要这里的正则表达式。只是在括号上分开:
(s.split(']')[-1] for s in example_str.split('['))
您的尝试无效的唯一原因:
re.findall(r"(.*?)\[.*\]+", example_str)
...是你在括号内做了一个非贪婪的比赛,这意味着它正在捕捉从第一个开放括号到最后一个关闭括号的所有内容,而不是只捕获第一对括号。
另外,最后+
似乎错了。如果您有'abc [def][ghi] jkl[mno]'
,是否要返回['abc ', '', ' jkl']
或['abc ', ' jkl']
?如果是前者,请不要添加+
。如果是后者,那么 - 但是你需要将整个括号内的模式放在一个非捕获组中:r'(.*?)(?:\[.*?\])+
。
如果在最后一个括号后面可能有其他文字,split
方法可以正常工作,或者您可以使用re.split
代替re.findall
...但是如果您想调整原文正则表达式,你可以。
在英语中,你想要的是在括号内的子串或之前的任何(非贪婪的)子串,对吧?
因此,您需要在\[.*?\]
和$
之间进行更改。当然,您需要将其分组才能编写替换,并且您不想捕获该组。所以:
re.findall(r"(.*?)(?:\[.*?\]|$)", example_str)
答案 1 :(得分:5)
如果从未嵌套括号:
([^[\]]+)(?:$|\[)
示例:
>>> import re
>>> s = 'Josie Smith [3996 COLLEGE AVENUE, SOMETOWN, MD 21003]Mugsy Dog Smith [2560 OAK ST, GLENMEADE, WI 14098]'
>>> re.findall(r'([^[\]]+)(?:$|\[)', s)
['Josie Smith ', 'Mugsy Dog Smith ']
说明:
([^[\]]+) # match one or more characters that are not '[' or ']' and place in group 1
(?:$|\[) # match either a '[' or at the end of the string, do not capture
答案 2 :(得分:3)
如果你想使用正则表达式并仍然处理嵌套括号,你可以使用:
import re
expr = re.compile("(?:^|])([^[\]]+)(?:\[|$)")
print(expr.findall("myexpr[skip this[and this]]another[and skip that too]"))
这将产生['myexpr', 'another']
。
我们的想法是匹配字符串开头或]
与字符串结尾或[
之间的任何内容。
答案 3 :(得分:2)
你可以这样做:
outside = re.findall(r"[^[]+(?=\[[^]]*]|$)", example_str)
换句话说:所有不是开头方括号后跟方括号内的东西或字符串的结尾