使用正则表达式保留中间字符串
Retain intermediate string using regex
我想在多个 python 代码文件中的所有出现处将子字符串附加到字符串模式。然而,原始字符串遵循一种模式,并且每次都不是完全相同的字符串。
以下是变化的一些示例:
Original Code: a.b();
Want Code: a.b().c();
Original Code: a.b(param1=1);
Want Code: a.b(param1=1, param2=2).c();
Original Code: a.b(param1=1, param2=2);
Want Code: a.b(param1=1, param2=2).c();
Original Code: a.b(param1=D());
Want Code: a.b(param1==D()).c();
Original Code: X(a.b(param1=D()));
Want Code: X(a.b(param1==D()).c());
更新:
由于我试图替换文件中的代码,该文件包含缩进和换行以提高可读性:
例如
Original Code: X(a.b(
param1=D()
)
);
Want Code: X(a.b(
param1=D()
).c()
);
Original Code: X(a.b(
param1=D(),
param2="qwerty"
)
);
Want Code: X(a.b(
param1=D(),
param2="qwerty"
).c()
);
Original Code: X(a.b(
newObj())
);
Want Code: X(a.b(
newObj()).c()
);
我不太关心函数 b 中传递的参数。我只需要在每次调用 a.b() 时追加调用 c()。
我正在使用正则表达式 'a.b(.*?)'
来检测适当的原始代码。我尝试使用
以下解决方案正则表达式:a.b().c()
或 a.b().c()
但无济于事。
这个怎么样:
模式:(a\.b\(.*?\))
替换:.c()
结果:
a.b(param1=1).c();
a.b(param1=1, param2=2).c();
a.b().c();
你可以使用
a\.b\([^()]*\)(?=;)
a\.b
按字面匹配并转义点
\([^()]*\)
使用否定字符从左括号匹配到右括号 class
(?=;)
正面前瞻,向右断言 ;
并替换为完整匹配项 \g<0>
,然后是 .c()
\g<0>.c()
例如:
import re
regex = r"a\.b\([^()]*\)(?=;)"
s = ("a.b();\n"
"a.b(param1=1);\n"
"a.b(param1=1, param2=2);")
result = re.sub(regex, r"\g<0>.c()", s)
if result:
print (result)
输出
a.b().c();
a.b(param1=1).c();
a.b(param1=1, param2=2).c();
匹配平衡括号
a\.b(\((?>[^()]++|(?1))*\))
模式匹配:
a\.b
匹配 .b
(
捕获 组 1
\(
匹配 (
(?>
原子组(无回溯)
[^()]++
匹配除 (
或 )
之外的任何字符出现 1 次以上
|
或
(?1)
递归第一个子模式(第 1 组)
)*
关闭群组并可选择重复
\)
匹配 )
)
关闭组 1
import regex
pattern = r'a\.b(\((?>[^()]++|(?1))*\))'
strings = [
"a.b();",
"a.b(param1=1);",
"a.b(param1=1, param2=2);",
"a.b(param1=d(abc=\"123\"));"
]
for s in strings:
m = regex.match(pattern, s)
if m:
print(f"{m.group()}.c()")
输出
a.b().c()
a.b(param1=1).c()
a.b(param1=1, param2=2).c()
a.b(param1=d(abc="123")).c()
我想在多个 python 代码文件中的所有出现处将子字符串附加到字符串模式。然而,原始字符串遵循一种模式,并且每次都不是完全相同的字符串。 以下是变化的一些示例:
Original Code: a.b();
Want Code: a.b().c();
Original Code: a.b(param1=1);
Want Code: a.b(param1=1, param2=2).c();
Original Code: a.b(param1=1, param2=2);
Want Code: a.b(param1=1, param2=2).c();
Original Code: a.b(param1=D());
Want Code: a.b(param1==D()).c();
Original Code: X(a.b(param1=D()));
Want Code: X(a.b(param1==D()).c());
更新: 由于我试图替换文件中的代码,该文件包含缩进和换行以提高可读性: 例如
Original Code: X(a.b(
param1=D()
)
);
Want Code: X(a.b(
param1=D()
).c()
);
Original Code: X(a.b(
param1=D(),
param2="qwerty"
)
);
Want Code: X(a.b(
param1=D(),
param2="qwerty"
).c()
);
Original Code: X(a.b(
newObj())
);
Want Code: X(a.b(
newObj()).c()
);
我不太关心函数 b 中传递的参数。我只需要在每次调用 a.b() 时追加调用 c()。
我正在使用正则表达式 'a.b(.*?)'
来检测适当的原始代码。我尝试使用
以下解决方案正则表达式:a.b().c()
或 a.b().c()
但无济于事。
这个怎么样:
模式:(a\.b\(.*?\))
替换:.c()
结果:
a.b(param1=1).c();
a.b(param1=1, param2=2).c();
a.b().c();
你可以使用
a\.b\([^()]*\)(?=;)
a\.b
按字面匹配并转义点\([^()]*\)
使用否定字符从左括号匹配到右括号 class(?=;)
正面前瞻,向右断言;
并替换为完整匹配项 \g<0>
,然后是 .c()
\g<0>.c()
例如:
import re
regex = r"a\.b\([^()]*\)(?=;)"
s = ("a.b();\n"
"a.b(param1=1);\n"
"a.b(param1=1, param2=2);")
result = re.sub(regex, r"\g<0>.c()", s)
if result:
print (result)
输出
a.b().c();
a.b(param1=1).c();
a.b(param1=1, param2=2).c();
匹配平衡括号
a\.b(\((?>[^()]++|(?1))*\))
模式匹配:
a\.b
匹配.b
(
捕获 组 1\(
匹配(
(?>
原子组(无回溯)[^()]++
匹配除(
或)
之外的任何字符出现 1 次以上
|
或(?1)
递归第一个子模式(第 1 组)
)*
关闭群组并可选择重复\)
匹配)
)
关闭组 1
import regex
pattern = r'a\.b(\((?>[^()]++|(?1))*\))'
strings = [
"a.b();",
"a.b(param1=1);",
"a.b(param1=1, param2=2);",
"a.b(param1=d(abc=\"123\"));"
]
for s in strings:
m = regex.match(pattern, s)
if m:
print(f"{m.group()}.c()")
输出
a.b().c()
a.b(param1=1).c()
a.b(param1=1, param2=2).c()
a.b(param1=d(abc="123")).c()