以下代码在字符串中查找要替换的组的正则表达式的名称。我想使用它来分别将名称name_1
,name_2
和not_escaped
更改为test_name_1
,test_name_2
和test_not_escaped
。在匹配m
中,每个名称等于m.group(2)
。我怎样才能做到这一点 ?
p = re.compile(r"(?<!\\)(\\\\)*\\g<([a-zA-Z_][a-zA-Z\d_]*)>")
text = r"</\g<name_1>\g<name_2>\\\\\g<not_escaped>\\g<escaped>>>"
for m in p.finditer(text):
print(
'---',
m.group(),
m.group(2)
)
这给出了以下输出。
---
\g<name_1>
name_1
---
\g<name_2>
name_2
---
\\\\\g<not_escaped>
not_escaped
答案 0 :(得分:1)
您需要使用\<digit>
反向引用重现整个组0文本,以重新使用捕获的组:
p.sub(r'\1\\g<test_\2>', text)
此处\1
表示初始反斜杠组,\2
表示名称前缀为test_
。
要实现此目的,您需要将*
移动到第一个捕获组,以确保捕获的组不匹配:
p = re.compile(r"(?<!\\)((?:\\\\)*)\\g<([a-zA-Z_][a-zA-Z\d_]*)>")
我使用非捕获组((?:...)
)来保持反斜杠组合在一起。
演示:
>>> text = r"</\g<name_1>\g<name_2>\\\\\g<not_escaped>\\g<escaped>>>"
>>> p = re.compile(r"(?<!\\)((?:\\\\)*)\\g<([a-zA-Z_][a-zA-Z\d_]*)>")
>>> print(p.sub(r'\1\\g<test_\2>', text))
</\g<test_name_1>\g<test_name_2>\\\\\g<test_not_escaped>\\g<escaped>>>
答案 1 :(得分:0)
实现此目的的最简单方法是使用一系列对str.replace
的三个简单调用,而不是使用正则表达式进行替换:
import re
p = re.compile(r"(?<!\\)(\\\\)*\\g<([a-zA-Z_][a-zA-Z\d_]*)>")
text = r"</\g<name_1>\g<name_2>\\\\\g<not_escaped>\\g<escaped>>>"
for m in p.finditer(text):
if m.groups(2):
replacement = m.groups(2)[1]
text = text.replace(replacement, 'test_' + replacement)