9

我正在尝试使用正则表达式获取括号外的任何文本。

示例字符串

乔西·史密斯 [3996 COLLEGE AVENUE, SOMETOWN, MD 21003]Mugsy Dog Smith [2560 OAK ST, 格伦米德, 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]组合的字符串,但我假设一个字符串中可能有任意数量的组合。

4

4 回答 4

12

如果没有嵌套括号,您可以这样做:

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)
于 2013-06-24T20:59:59.040 回答
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
于 2013-06-24T21:01:24.743 回答
3

如果您想使用正则表达式并仍然处理嵌套括号,您可以使用:

import re
expr = re.compile("(?:^|])([^[\]]+)(?:\[|$)")

print(expr.findall("myexpr[skip this[and this]]another[and skip that too]"))

这将产生['myexpr', 'another'].

这个想法是匹配字符串或 a 的开头和字符串或 a]的结尾之间的任何内容[

于 2017-01-19T10:16:11.280 回答
2

你可以这样做:

 outside = re.findall(r"[^[]+(?=\[[^]]*]|$)", example_str)

换句话说:所有不是左方括号后跟方括号内的内容或字符串结尾的内容

于 2013-06-24T20:59:50.140 回答