在正则表达式中重复正则表达式块

时间:2014-11-17 13:53:18

标签: python regex

我正在试图找出一个很好的正则表达式来匹配以下内容:

1:[any chars here except newlines]|1:[any chars here except newlines]... 

我希望我的正则表达式能够匹配这种类型的无数次重复。最简单的我已经找到了'(1:[^|]*\|)\1+',但是由于两个原因它不起作用。首先,只能找到在字符串末尾有一个额外管道的字符串。其次,第一次捕获中的文本必须始终相同。

我可以使用拆分来解决这个问题,但我只是想知道在正则表达式中是否有一种很好的方法。

2 个答案:

答案 0 :(得分:3)

将量词应用于整个组:

^(?:1:[^|\n]*\|?)+(?<!\|)$

^断言字符串开头的位置。然后匹配1:后跟任何非|或换行符,或更多次(由*表示)的字符。整个组可以重复一次或更多次(由+表示)。 (?<!\|)是负面的背后隐藏,断言最后一个字符不是|$在字符串末尾断言位置。

它匹配所有这些:

1:foo
1:foo|1:bar
1:foo|1:bar|1:baz
1:foo|1:bar|1:baz|1:bak

但不会匹配

1:foo|

和类似的。

RegEx Demo

答案 1 :(得分:1)

你可以这样做,

^(1:[^|\n]*)(?:\|(?1))*$

DEMO

(?1)递归第一个捕获组。在here了解有关递归正则表达式的更多信息。

对于不支持递归正则表达式的语言。

^(?:1:[^|\n]*)(?:\|1:[^|\n]*)*$

DEMO

Python代码:

In [10]: import re

In [11]: s = """1:[any chars here except newlines]|1:[any chars here except newlines]
...: 1:[any chars here except newlines]
...: 1:foo
...: 1:foo|1:bar
...: 1:foo|1:bar|1:baz
...: 1:foo|1:bar|1:baz|1:bak
...: 1:foo|"""
In [14]: for i in re.findall(r'(?m)^(?:1:[^|\n]*)(?:\|1:[^|\n]*)*$', s):
    ...:     print(i)
    ...:     
1:[any chars here except newlines]|1:[any chars here except newlines]
1:[any chars here except newlines]
1:foo
1:foo|1:bar
1:foo|1:bar|1:baz
1:foo|1:bar|1:baz|1:bak