在Python中捕获重复模式

时间:2020-03-15 18:11:09

标签: python regex

我正在尝试实现某种降价行为,例如Python日志格式化程序的行为。

让我们以这个字符串为例:

**This is a warning**: Virus manager __failed__

一些正则表达式之后,该字符串已失去语法等降价标记,并变成了bash代码:

\033[33m\033[1mThis is a warning\033[0m: Virus manager \033[4mfailed\033[0m\033[0m

但是应该将其压缩为

\033[33;1mThis is a warning\033[0m: Virus manager \033[4mfailed\033[0m

除了许多其他无法解决的解决方案之外,我还尝试了以下方法:

(\\033\[([\d]+)m){2,} =>捕获:带有g1'\ 033 [1m'和g2'1'的\033[33m\033[1m和带有g1'\ 033 [0m'和g2'0'的\033[0m\033[0m / p>

(\\033\[([\d]+)m)+的结果很多,不好

(?:(\\033\[([\d]+)m)+)有许多结果,尽管如果我理解正确,这是重复模式的推荐方法,

和其他人..

我的目标是取得成果:

输入 \033[33m\033[1mThis is a warning\033[0m: Virus manager \033[4mfailed\033[0m\033[0m

输出

匹配1 033[33m\033[1m

Group1 :33

Group2 :1

第2场 033[0m\033[0m

Group1 :0

Group2 :0

换句话说,捕获那些“重复的”而不是单独的,所以我可以将它们与regex子融合。

3 个答案:

答案 0 :(得分:1)

问题中尚不清楚要修改的字符串中的模式。例如,033是固定的,还是025甚至是25?我在使用正则表达式时做了一些假设

r" ^(\\0(\d+)\[\2)[a-z]\\0\2\[(\d[a-z].+)

以获得两个要组合的捕获组,用分号分隔。我试图在下面阐明我的假设,部分是为了帮助OP修改此正则表达式以满足替代要求。

Demo

正则表达式执行以下操作:

^           # match beginning of line
(           # begin cap grp 1
  \\0       # match '\0'
  (\d+)     # match 1+ digits in cap grp 2
  \[        # match '['
  \2        # match contents of cap grp 2
)           # end cap grp 1
[a-z]       # match a lc letter
\\0         # match '\0'      
\2          # match contents of cap grp 2
\[          # match '['
(\d[a-z].+) # match a digit, then lc letter then 1+ chars to the
            #   end of the line in cap grp 3

如您所见,在第1组中捕获的字符串部分为

\033[33

我假设此字符串的现在为033的部分必须是两个或多个以零开头的数字,并且数字字符串的第二次出现由零之后的相同数字组成。这是通过捕获捕获组2中'0'(33)之后的数字,然后使用向后引用\2来完成的。

字符串的下一部分将被替换,因此不会被捕获:

m\\033[

我假设m必须是一个小写字母(或者应该是原义的m?),反斜杠和零以及必填项,并且以下数字必须再次与的内容匹配捕获组2。

字符串的其余部分

1mThis is a warning\033[0m: Virus manager \033[4mfailed\033[0m\033[0m

是在捕获组3中捕获的。在这里,我假设它以一位数字开头(也许应该是\d+),然后是一个小写字母,该小写字母不必与匹配的小写字母相同较早(尽管可以由另一个捕获组强制实施)。在那一点上,我已经将行的其余部分与.+进行了匹配,并放弃了该字符串部分中的匹配模式。

另外一个可能只有两个捕获组,捕获组现在是#2,成为#1,而#2是要用分号替换的字符串的一部分。

答案 1 :(得分:1)

您要匹配地重复匹配GetButtonDown的文本块,并用分号将\033[\d+m之后的数字连接起来。

您可以使用

[

请参见Python demo online

re.sub(r'(?:\\033\[\d+m){2,}', lambda m: r'\033['+";".join(set(re.findall(r"\[(\d+)", m.group())))+'m', text) 模式将匹配两个或更多(?:\\033\[\d+m){2,} +一个或多个数字+ \033[文本块的序列,然后将匹配项传递给lambda表达式,其中输出将是:1)m,2)用\033[提取[之后的所有数字,然后用re.findall(r"\[(\d+)", m.group())去重,然后3)set

答案 2 :(得分:0)

对于您在此处描述的情况,这非常简单;只需从左到右写出您想要匹配和捕获的内容。重复捕获块对您无济于事,因为结果将仅返回最近捕获的值。

\\033\[(\d+)m\\033\[(\d+)m
相关问题