替换出现在两个特定单词之间的一组字符串的所有出现
Posted
技术标签:
【中文标题】替换出现在两个特定单词之间的一组字符串的所有出现【英文标题】:replace all occurrences of a set of strings, which appear between two specific words 【发布时间】:2022-01-24 01:38:14 【问题描述】:我正在编写一个 python 脚本,它将帮助我使用 re.sub 功能替换我的 c++ 应用程序中的日志框架。
旧语法如下所示:
old_log_info("this is an integer: %i, this is a double: %d", 1, 2.0);
old_log_error("this is an integer: %i, this is a double: %d", 1, 2.0);
新语法:
new_log_inf("this is an integer: , this is a double: ", 1, 2.0);
new_log_err("this is an integer: , this is a double: ", 1, 2.0);
它也必须适用于多行语句,即:
old_log_info(
"this is an integer: %i, this is a double: %d",
1,
2.0);
应该变成:
new_log_inf(
"this is an integer: , this is a double: ",
1,
2.0);
替换函数名称很简单,但替换格式说明符(%i
、%d
等)仅如果出现在日志表达式中则不是。 %i
在:
printf("this is an integer: %i", 1);
应该保持不变。
我尝试使用环视来隔离old_log_info(
和最近的);
之间的子字符串:
re.sub(r'(?s)(?<=old_log_info)(?=\);)', '', code)
但我不知道如何只替换该匹配中的格式说明符而不是整个匹配。
【问题讨论】:
两个问题,你用什么日志功能?你知道你想要替换的日志行的文本吗?我猜你的例子只是一个例子,实际上并不是你要替换的。 你能用正则表达式展示你一直在玩什么吗,否则你可能不在正确的地方。 这是一个工作项目,我们正在使用 2 个不同的内部框架,我们想用薄包装的 spdlog 替换它们,但这真的无关紧要 - 例子很详尽 - 如果你发现一个“日志记录功能”然后用花括号替换调用中的所有格式说明符,并且不执行任何其他操作。我已经制作了新接口,只需更改函数名称并替换其参数中的格式说明符即可完成工作。 【参考方案1】:您可以使用两层正则表达式。一种是查找要在其中进行更改的函数,另一种是实际进行更改。
下面是一个逻辑示例。请注意,如果函数中的文本包含);
,则它不起作用,这种情况下最好通过解析替换第一级正则表达式(如果是这种情况,请提供代码示例)。
code = '''some code %i
old_log_info("this is an integer: %i, this is a double: %d", 1, 2.0);
printf("this is an integer: %i", 1);'''
import re
def repl(m):
inside = re.sub('%[id]', '', m.group(2))
return f'new_log_info(inside);'
new_code = re.sub('(old_log_info)\((.*?)\);', repl, code)
输出:
some code %i
new_log_info("this is an integer: , this is a double: ", 1, 2.0);
printf("this is an integer: %i", 1);
【讨论】:
这在它的简单和聪明方面非常出色。完成工作,谢谢你:) 解决方案中缺少一件事 - 内联的 DOTALL 标志:new_code = re.sub('(?s)(old_log_info)((.*?));', repl, code ) 或作为调用的参数:new_code = re.sub('(old_log_info)((.*?));', repl, code, flags=re.DOTALL)。没有这个标志,多行表达式将无法正确处理。 @mozway 你能看看这个question吗?以上是关于替换出现在两个特定单词之间的一组字符串的所有出现的主要内容,如果未能解决你的问题,请参考以下文章
USACO4.3 Letter Game枚举·细节