正则表达式获取捕获组的大小
Regex to get the size of capturing group
是否可以编写一个正则表达式,稍后我可以在同一个正则表达式中以某种方式引用“第一个捕获组的长度”?我在这里想要实现的是捕获 1
的连续出现,然后是 2
的连续出现的确切数量。
我想要类似的东西
r"(1*)(2{length()})" # where `length()` 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)
...
如果您不愿意使用正则表达式,请考虑拆分成一个列表并使用列表操作
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 模拟递归的重复
使用前瞻是对涵盖此内容的人的错误判断
通过将其标记为重复来提出问题。只是判断力差...
可以用 pythons regex 模块来完成。
需要使用递归。
这样做是因为它实际上只是嵌套的定界符。
1
1
1
2
2
2
1(?>[^12]++|(?R))*2
https://regex101.com/r/4Nxtvl/1
# 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
为了不允许内部内容使用1(?>(?R))*2
https://regex101.com/r/mSUIp0/1
要添加边界条件,包含对组的递归,
然后用边界结构围绕它。
(?<!\d)(1(?>[^12]++|(?1))*2)(?!\d)
https://regex101.com/r/SSr1zV/1
(?<! \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
为了不允许内部内容使用(?<!\d)(1(?>(?1))*2)(?!\d)
https://regex101.com/r/VI6w0Y/1
是否可以编写一个正则表达式,稍后我可以在同一个正则表达式中以某种方式引用“第一个捕获组的长度”?我在这里想要实现的是捕获 1
的连续出现,然后是 2
的连续出现的确切数量。
我想要类似的东西
r"(1*)(2{length()})" # where `length()` 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)
...
如果您不愿意使用正则表达式,请考虑拆分成一个列表并使用列表操作
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 模拟递归的重复
使用前瞻是对涵盖此内容的人的错误判断
通过将其标记为重复来提出问题。只是判断力差...
可以用 pythons regex 模块来完成。
需要使用递归。
这样做是因为它实际上只是嵌套的定界符。
1
1
1
2
2
2
1(?>[^12]++|(?R))*2
https://regex101.com/r/4Nxtvl/1
# 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
为了不允许内部内容使用1(?>(?R))*2
https://regex101.com/r/mSUIp0/1
要添加边界条件,包含对组的递归,
然后用边界结构围绕它。
(?<!\d)(1(?>[^12]++|(?1))*2)(?!\d)
https://regex101.com/r/SSr1zV/1
(?<! \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
为了不允许内部内容使用(?<!\d)(1(?>(?1))*2)(?!\d)
https://regex101.com/r/VI6w0Y/1