繁体   English   中英

Python正则表达式捕获组

[英]Python Regex Capturing Group

string1 = "abcdbcdbcde"

我想将string1提取为三部分:(第一部分和第三部分可以为空字符串)

第一部分:

第二部分(某些字符串的重复):bcdbcdbcd

第三部分:e

import re

string1 = "abcdbcdbcde"
m = re.match("(.*)(.+){2,}(.*)", string1)
print m.groups()[0], m.groups()[1], m.groups()[2]

当然,上面的代码不起作用。

据我所知,括号运算符可用作RegEx捕获组或对模式的引用。 如何在这两种情况下同时使用括号运算符?

我想要的是:

m.groups()[0] = "a"
m.groups()[1] = "bcdbcdbcd"
m.groups()[2] = "e"

如果第二部分应该是同一字符串的重复,则可以使用可选的第一部分a和第三部分。 对于第二部分,您可以使用捕获组和反向引用

^.?(.+)\1+.?$

正则表达式演示

或者,如果要所有捕获组:

^(.?)((.+)\3+)(.?)$
  • ^字符串开头
  • (.?)组1,可选匹配任何字符
  • (第2组
    • (.+)\\3+组3,匹配任何字符,然后反向引用到组3重复的1+字母
  • )第三组
  • (.?)组4,可选匹配任何字符
  • $字符串结尾

正则表达式演示

我认为无法完全满足您的要求,因为需要更多的捕获组(至少要重复用\\1匹配相同的字符串)。

但是您可以尝试(\\w+)((\\w+)\\3+)(\\w+)

它将包括4个捕获组。 通常,第一个捕获组将包含a ,最后一个将包含e ,第二个将包含重复的字符串,其余无关。

说明:

\\w+ -匹配一个或多个单词字符

\\3+ -匹配在第三个捕获组中捕获的字符串,一次或更多次

演示

以下正则表达式应该起作用(如下所示):

^(.*?)((.+?)\3+)(.*)

说明:

^      # Start of string
(.*?)  # Match any number of characters, as few as possible, until...
(      # (Start capturing group #2)
 (.+?) # ... a string is matched (and captured in group #3)
 \3+   # that is repeated at least once.
)      # End of group #2
(.*)   # Match the rest of the string

在regex101.com上进行实时测试。

注意:如果字符串很长并且没有明显的重复,这将具有非常糟糕的性能特征(我认为是O(n!) ),因为正则表达式引擎必须检查子字符串的每个排列。 请参阅灾难性的回溯

我对这个问题的看法:

import re

def match(s, m):
    m = re.match("(.*?)?((?:" + m + "){2,})(.*?)?$", s)
    return (m.groups()[0], m.groups()[1], m.groups()[2]) if m else (None, None, None)

print(match("abcdbcdbcde", "bcd"))
print(match("bcdbcdbcd", "bcd"))
print(match("abcdbcdbcd", "bcd"))
print(match("bcdbcdbcde", "bcd"))
print(match("axxbcdbcdxxe", "bcd"))
print(match("axxbcdxxe", "bcd")) # only one bcd in the middle

打印:

('a', 'bcdbcdbcd', 'e')
('', 'bcdbcdbcd', '')
('a', 'bcdbcdbcd', '')
('', 'bcdbcdbcd', 'e')
('axx', 'bcdbcd', 'xxe')
(None, None, None)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM