我们的 C++ 项目的日志记录工具即将重构为使用重复的左移运算符(以 QtqDebug()
语法的方式)而不是 printf 样式的可变参数函数。
假设日志记录对象被调用logger
。假设我们要显示我们连接的服务器的 ip 和端口。在当前的实现中,用法是:
logger.logf("connected to %s:%d", ip, port);
重构后,上述调用将变为:
logger() << "connected to" << ip << ":" << port;
手动替换所有这些调用将非常繁琐且容易出错,所以很自然地,我想使用正则表达式。作为第一遍,我可以替换.logf(...)
调用,产生
logger() "connected to %s:%d", ip, port;
但是,将此字符串重新格式化为左移语法是我遇到问题的地方。我设法创建了单独的正则表达式来捕获printf 占位符和逗号分隔的参数。但是,我不知道如何正确地将两者关联起来。
为了避免重复相当笨拙的正则表达式,我将使用占位符(printf)
来引用printf 占位符正则表达式(返回命名的 group token
),并(args)
引用逗号分隔的参数正则表达式(返回命名的 group arg
)。下面,我将给出应用于上述行相关部分的各种尝试的输出,即:
"connected to %s:%d", ip, port
/(printf)(args)/g
不产生匹配。/(printf)*(args)/g
产生两个匹配,包含ip
和port
在命名组中arg
(但没有在token
)。/(printf)(args)*/g
得到相反的结果:它产生两个匹配,在命名的 group中包含%s
和,但在.%d
token
arg
/(printf)*(args)*/g
返回 3 个匹配项:前两个包含%s
和%d
intoken
,第三个包含port
inarg
。但是,regexp101 报告“20 个匹配项 - 207 个步骤”并且似乎在每个字符之前都匹配。我想也许我需要指定第一个捕获组总是在双引号之间。但是,既不
/"(printf)"(args)/g
也不/"(printf)(args)/g
产生任何匹配。/(printf)"(args)/g
产生一个(不正确的)匹配,包含%d
in grouptoken
和ip
inarg
,并且替换会消耗这两个字符串之间的整个字符串(因此输入#
替换字符串会导致"connected to %s:#, port
. 显然,这不是预期的结果,但它是我可以的唯一版本至少在一次比赛中获得两个命名组。
任何帮助是极大的赞赏。
编辑以纠正损坏的格式