【问题标题】:regex to get all text outside of brackets正则表达式获取括号外的所有文本
【发布时间】:2013-06-24 20:56:47
【问题描述】:

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

示例字符串

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

【问题讨论】:

  • 括号可以嵌套吗
  • @aaronman 我假设不会有任何嵌套括号。好问题。

标签: python regex


【解决方案1】:

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

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)

【讨论】:

  • 如果在最后一对括号之后有任何文本怎么办? (仅指您的正则表达式;您的拆分解决方案有效)
  • 啊,是的,这一切都说得通。我自己更喜欢split 解决方案。
  • @TimPietzcker:您可以添加与 OP 的原始正则表达式相同的样式;有点复杂的是,写它的明显方法需要一个非捕获组。编辑了答案以显示如何。
  • \]+ 无论如何都是错误的,因为它只重复括号,而不是括号中的文本。
  • 好点。正如我所说,我认为 OP 无论如何都不想要它,但我会编辑答案。
【解决方案2】:

如果没有嵌套括号:

([^[\]]+)(?:$|\[)

例子:

>>> 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

【讨论】:

  • 这个效果更好,因为它不像@abamert's那样返回空字符串
  • 这捕获了结尾 [ 不是吗?或者至少这就是我得到的:regex101.com/r/G43H7X/1 我认为([^[\]]+)(?:$|(?=\[)) 会更好一点,以便只提取内容
【解决方案3】:

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

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

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

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

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

【讨论】:

    【解决方案4】:

    你可以这样做:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-12
      • 1970-01-01
      • 2020-03-14
      • 2022-12-08
      • 2019-01-20
      • 1970-01-01
      相关资源
      最近更新 更多