Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Regex以获取捕获组的大小_Python_Regex_Re - Fatal编程技术网

Python Regex以获取捕获组的大小

Python Regex以获取捕获组的大小,python,regex,re,Python,Regex,Re,是否可以编写一个正则表达式,以便稍后在同一正则表达式中引用“第一个捕获组的长度”?我在这里试图实现的是捕获连续出现的1,然后是连续出现的2 我想要像这样的东西 r"(1*)(2{length(\1)})" # where `length(\1)` should give me the length of capture group 1 应该匹配 1122 # two 1's followed by two 2's 111222 # three 1's followed by

是否可以编写一个正则表达式,以便稍后在同一正则表达式中引用“第一个捕获组的长度”?我在这里试图实现的是捕获连续出现的
1
,然后是连续出现的
2

我想要像这样的东西

r"(1*)(2{length(\1)})" # where `length(\1)` should give me the length of capture group 1
应该匹配

1122 # two 1's followed by two 2's
111222 # three 1's followed by three 2's
121122111222 # should match `12` and `1122` and `111222` separately
不应该匹配

122 # there are two 2's following one 1
112 # there are two 1's but only one 2
11222 # same as above but with different occurrences
11122 # same as above but with different occurrences

如果顺序1的最大数量足够少,则可以枚举选项。比如:

r'(12)|(1122)|(1{3}2{3})' etc
您甚至可以生成正则表达式。如果没有太多的递归,长正则表达式的效率会出人意料

for i in range(1:50):
    regex += r"|1{" + str(i) + r"}2{" + str(i) + r"}"
您还必须根据需要添加边界

如果您不介意进行两次传递,可以从重新匹配对象获得长度:

ONES = re.compile(r'1+')
match = ONES.search(string)
if match is not None:
    length = match.end() - match.start()
TWOS = re.compile(r'2{' + str(length) + r'}')
string = string[match.end():]
match = TWOS.search(string)
...
如果你不愿意使用正则表达式,考虑分解成一个列表,使用列表操作< /p> < P> <强> Update <强>我猜你可以使用一些荒谬的java前瞻递归模拟,这是不工作的。 或者你可以用Python来做

>>> import regex
>>> rx_1_2 = r"(?m)^(1(?>(?1))*2)$"
>>>
>>> input = '''
... 111222222
... 11222234
... 1111222
... 111222
... 1122
... 12
... '''
>>> res = regex.findall( rx_1_2, input )
>>> print( res )
['111222', '1122', '12']
这个问题被标记为Java模拟递归的副本
对报道这件事的人来说,使用lookaheads是非常糟糕的判断 通过将其标记为副本来提问。只是判断力太差了


它可以通过pythons regex模块完成。
需要使用递归。
这样做是因为它实际上只是嵌套的分隔符

1
  1
    1
    2
  2
2
1(?>[^12]++|(?R))*2

不允许内部内容使用
1(?>(?R))*2


若要添加边界条件,请包含对组的递归,
然后用边界构造将其包围

(?[^12]++(1))*2)(?!\d)

(?#原子群
[^12]++#所有格,不是1或2
|#或,
(?1)#递归正则表达式组1
)*#结束群集,执行0到多次
2                       # 2
)#(一完)
(?!\d)#前面没有数字

要禁止使用内部内容,请使用
(?(?1))*2)(?!\d)

正则表达式语言中没有此类构造。您可以使用python
regex
引擎执行此操作。它是用递归完成的。@Maxt8r你能把它写进一个答案吗?我很好奇。@WiktorStribiżew dupe提到了如何用Java和PHP实现这一点。我想知道如何在python中实现这一点发布在的PCRE解决方案受PyPi regex库的支持,因此也是一样的。感谢您的回复,选项1对我来说不是一个好选项,即使我可以生成动态regex字符串,选项2似乎很有希望,如果以后没有其他答案,我会将此标记为答案如果使用regex works的答案接受这一点。谢谢回答,递归regex是我不知道的东西,因此+1,但是从regex101链接来看,它不能与任何测试输入匹配,因为前两个的
2
的数量大于
1
,第三个有4个
1
,然后是3个
2
。我希望在
1
后面跟
2
出现“完全”相同的情况。我已经给出了在比赛中不匹配的东西question@python_learner是的,这只是一个简单的调整。根据需要在前后添加边界要求。为此,递归一个组而不是整个正则表达式。我会安装一个mod。如果你不想使用regex模块,这是没有意义的。将此标记为一个答案,因为这已经被证明对我很有用,值得注意的是
(?m)^(1(?>(?1))*2)$
无法匹配
121122111222
,但我相信这是我以后可以调整的,这个dupe是用java和php编写的,这不是这个问题所要求的++,不过
^(1(?1)*+2)$
会更有效率
                         # Recursion 
 1                       # 1
 (?>                     # Atomic group
      [^12]++                 # Possesive, not 1 or 2
   |                        # or,
      (?R)                    # Recurse the regex
 )*                      # End cluster, do 0 to many times
 2                       # 2
 (?<! \d )               # Not a digit behind
 (                       # (1 start), Recursion code group
    1                       # 1
    (?>                     # Atomic group
       [^12]++                 # Possesive, not 1 or 2
     |                        # or,
       (?1)                    # Recurse the regex group 1
    )*                      # End cluster, do 0 to many times
    2                       # 2
 )                       # (1 end)
 (?! \d )                # Not a digit ahead