什么正则表达式将捕获大括号/括号内的多个实例?

时间:2016-02-27 13:12:36

标签: python regex

如何使用正则表达式捕获括号内的每个空格字符\ +?例如,在字符串中, "abc and 123 {foo-bar bar baz } bit {yummi tummie} byte." 我应该在{}内找到四个匹配 - 但没有别的。假设Python语言并且字符串内容未知。

编辑:还假设没有嵌套大括号。

3 个答案:

答案 0 :(得分:5)

A lookahead可以检查前面是否有},而中间没有{

\s+(?=[^{]*})
  • \s是空格字符[ \t\r\n\f]的{​​{3}}。匹配short一个或多个。

  • 如果(?=[^{]*})之间有+,则
  • }向前看。

non {

答案 1 :(得分:3)

>>> s = 'abc   and 123 {foo-bar     bar baz } bit {yummi tummie} byte.'
>>> inside_braces = re.findall(r'\{.*?\}', s)
>>> spaces_inside_braces = [re.findall(r' +', match) for match in inside_braces]
>>> [match for mlist in spaces_inside_braces for match in mlist]  # flatten list
['     ', ' ', ' ', ' ']
  1. ?我们需要r'\{.*?\}'才能非贪婪地匹配大括号。
  2. 可以在一行中完成所有操作,但这样做太长了。
  3. 我想不出用一个正则表达式来完成所有这些操作的方法。这似乎是不可能的,因为我们有递归(甚至左递归):即,模式应该匹配 {之后的 .w的任何数字 }秒。 IIRC正则表达式无法解决这个问题,即使后视不需要固定长度的模式。

答案 2 :(得分:-1)

如果您可以使用alternate regex module,那么可以使用单个正则表达式执行此操作。但它很复杂且难以理解。但它正确处理悬挂支撑。

regex模块支持访问所有捕获组的之前匹配,这对于以下工作至关重要:

>>> import regex
>>> # The regex behavior version seems to make no difference in this case, so both '(?V0)...' and '(?V1)...' will work.
>>> pattern = r'(?V0)[{]   (?P<u>\s+)?  (?: (?: [^\s}]+ (?P<u>\s+) )*  [^\s}]+ (?P<u>\s+)? )?   [}]'
>>> string = 'abc   and 123 {foo-bar     bar baz } bit {yummi tummie} byte.'
>>> [s for m in regex.finditer(pattern, string, regex.VERBOSE) for s in m.captures('u')]
['     ', ' ', ' ', ' ']

简单地说,这个正则表达式找到'{' blanks? ((nonblanks blanks)* nonblanks blanks?)? '}'形式的匹配项,并将所有空白部分分配给名为u(?P<u>...))的同一个捕获组。

它也适用于包含不匹配的{}

的字符串
>>> # Even works with dangling braces:
>>> badstring = '}oo} { ab  a   b}}  xy {xy  x y}cd {{   cd  } e{e }f{ f}  { }{} }{'
>>> # Fully flattened result:
>>> [s for m in regex.finditer(pattern, badstring, regex.VERBOSE) for s in m.captures('u')]
[' ', '  ', '   ', '  ', ' ', '   ', '  ', ' ', ' ', ' ']
>>> # Less flattened (e.g. for verification):
>>> [v for m in regex.finditer(pattern, badstring, regex.VERBOSE) for v in m.capturesdict().values()]
[[' ', '  ', '   '], ['  ', ' '], ['   ', '  '], [' '], [' '], [' '], []]

在Python 3.5.1 x64,regex 2016.3.2上测试。