这是Python正则表达式的后续行动- 替换单引号和括号线程.
任务:
示例输入字符串:
RSQ(name['BAKD DK'], name['A DKJ'])
SMT(name['BAKD DK'], name['A DKJ'], name['S QRT'])
Run Code Online (Sandbox Code Playgroud)
期望的产出:
XYZ(BAKD DK, A DKJ)
XYZ(BAKD DK, A DKJ, S QRT)
Run Code Online (Sandbox Code Playgroud)
类似name['something']项目的数量是可变的.
目前的解决方案:
目前,我通过两个单独的re.sub()调用来完成它:
>>> import re
>>>
>>> s = "RSQ(name['BAKD DK'], name['A DKJ'])"
>>> s1 = re.sub(r"^(\w+)", "XYZ", s)
>>> re.sub(r"name\['(.*?)'\]", r"\1", s1)
'XYZ(BAKD DK, A DKJ)'
Run Code Online (Sandbox Code Playgroud)
问题:
是否可以将这两个re.sub()调用组合成一个?
换句话说,我想在字符串的开头替换一些东西,然后在多个类似的东西之后替换,所有这一切都在一个去.
Cas*_*yte 13
您确实可以使用正则表达式模块和重复捕获.主要的兴趣是你可以检查匹配字符串的结构:
import regex
regO = regex.compile(r'''
\w+ \( (?: name\['([^']*)'] (?: ,[ ] | (?=\)) ) )* \)
''', regex.VERBOSE);
regO.sub(lambda m: 'XYZ(' + (', '.join(m.captures(1))) + ')', s)
Run Code Online (Sandbox Code Playgroud)
(请注意,您可以替换"name"的\w+,或者你想要的东西没有问题.)
你可以做到这一点.虽然我觉得它不太可读.如果你开始添加更多模式来替换,那么这样做可能会变得难以驾驭.它利用了替换字符串也可以是一个功能的事实.
s = "RSQ(name['BAKD DK'], name['A DKJ'])"
re.sub(r"^(\w+)|name\['(.*?)'\]", lambda m: 'XYZ' if m.group(1) else m.group(2), s)
Run Code Online (Sandbox Code Playgroud)
请不要在我必须维护的任何代码中执行此操作.
您正在尝试解析语法上有效的Python.使用ast了点.它更易读,更容易扩展到新的语法,并且不会在一些奇怪的角落情况下崩溃.
工作样本:
from ast import parse
l = [
"RSQ(name['BAKD DK'], name['A DKJ'])",
"SMT(name['BAKD DK'], name['A DKJ'], name['S QRT'])"
]
for item in l:
tree = parse(item)
args = [arg.slice.value.s for arg in tree.body[0].value.args]
output = "XYZ({})".format(", ".join(args))
print(output)
Run Code Online (Sandbox Code Playgroud)
打印:
XYZ(BAKD DK, A DKJ)
XYZ(BAKD DK, A DKJ, S QRT)
Run Code Online (Sandbox Code Playgroud)