gpt4 book ai didi

c++ - 用于使用 ostream 左移语法替换 printf 样式调用的正则表达式

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:46:02 27 4
gpt4 key购买 nike

我们的 C++ 项目的日志工具将被重构为使用重复的左移运算符(以 Qt 的 qDebug() 语法的方式)而不是 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 placeholderscomma-delimited arguments .但是,我不知道如何正确关联这两者。

为了避免重复相当笨拙的正则表达式,我将使用占位符 (printf) 来引用 printf placeholder regex (返回命名组 token)和 (args) 来引用 comma-delimited arguments正则表达式(返回命名组 arg)。下面,我将给出应用于上述行相关部分的各种尝试的输出,即:

"connected to %s:%d", ip, port
  • /(printf)(args)/g 不产生匹配。

  • /(printf)*(args)/g 产生两个匹配项,在命名组 中包含 ipport code>arg(但 token 中没有任何内容)。

  • /(printf)(args)*/g 获得相反的结果:它产生两个匹配项,包含 %s%d 在命名组 token 中,但在 arg 中没有任何内容。

  • /(printf)*(args)*/g 返回 3 个匹配项:前两个包含 %s%dtoken中,第三个包含arg中的port。然而,regexp101 报告“20 个匹配项 - 207 个步骤”并且似乎在每个字符之前都匹配。

  • 我想也许我需要指定第一个捕获组始终在双引号之间。但是,/"(printf)"(args)/g/"(printf)(args)/g 都不会产生任何匹配项。

  • /(printf)"(args)/g 产生一个(不正确的)匹配,包含组 token 中的 %darg 中的 ip,替换会消耗这两个字符串之间的整个字符串(因此为替换字符串输入 # 会导致 ”连接到 %s:#,端口。显然,这不是预期的结果,但这是我至少可以在一次匹配中同时获得两个命名组的唯一版本。

非常感谢任何帮助。

已编辑以更正损坏的格式

最佳答案

免责声明:这是一个解决方法,它远非完美并且可能会导致错误 .提交更改时要小心,如果可以的话,让同事校对差异以减少干扰的可能性。


您可以尝试从解决方案中的最大参数数到最小值(这里我将从 3 到 0)进行多步替换。

让我们考虑 logger.logf("connected to %s:%d some %s random text", ip, port, test);

您可以将其与此正则表达式匹配:logger.logf\("(.*?)(%[a-z])(.*?)(%[a-z])(.*?)(%[a-z])(.*?)",(.*?)(?:, (.*?))?(?:, (.*?))?\);这将为您提供以下组:

1.  [75-88] `connected to `
2. [88-90] `%s`
3. [90-91] `:`
4. [91-93] `%d`
5. [93-99] ` some `
6. [99-101] `%s`
7. [101-113] ` random text`
8. [115-118] ` ip`
9. [120-124] `port`
10. [126-130] `test`

替换为logger() << "\1" << \8 << "\3" << \9 << "\5" << \10 << "\7";会给你

logger() << "connected to " << ip << ":" << port << " some " << test << " random text";


现在使用 2 个参数,示例字符串是 logger.logf("connected to %s:%d some random text", ip, port); , 对应的正则表达式为 logger.logf\("(.*?)(%[a-z])(.*?)(%[a-z])(.*?)",(.*?)(?:, (.*?))?\);

匹配如下:

1.  [13-26] `connected to `
2. [26-28] `%s`
3. [28-29] `:`
4. [29-31] `%d`
5. [31-48] ` some random text`
6. [50-53] ` ip`
7. [55-59] `port`

替换字符串:logger() << "\1" << \6 << "\3" << \7 << "\5";输出:

logger() << "connected to " << ip << ":" << port << " some random text";


输入logger.logf("Some %s text", port);

正则表达式 logger.logf\("(.*?)(%[a-z])(.*?)",(.*?)\);

替换 logger() << "\1" << \4 << "\3";

logger() << "Some " << port << " text";


空组呢?

假设输入不是 logger.logf("Some %s text", port);但是logger.logf("Some %s", port); .输出将是:

logger() << "Some " << port << "";

您必须删除 << ""把东西弄干净。

关于c++ - 用于使用 ostream 左移语法替换 printf 样式调用的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38257158/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com