我正在尝试实现某种降价行为,例如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子融合。
答案 0 :(得分:1)
问题中尚不清楚要修改的字符串中的模式。例如,033
是固定的,还是025
甚至是25
?我在使用正则表达式时做了一些假设
r" ^(\\0(\d+)\[\2)[a-z]\\0\2\[(\d[a-z].+)
以获得两个要组合的捕获组,用分号分隔。我试图在下面阐明我的假设,部分是为了帮助OP修改此正则表达式以满足替代要求。
正则表达式执行以下操作:
^ # 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
之后的数字连接起来。
您可以使用
[
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