【问题标题】:Match Variadic Function - Vim Regex匹配可变参数函数 - Vim 正则表达式
【发布时间】:2021-12-29 21:19:57
【问题描述】:

假设你有以下 C 函数:

void foo(int a, int b, const char* fmt, ...)

并且您想用bar() 查找/替换foo() 的函数调用

void bar(int a, int b, int c, const char* fmt, ...)

您如何将foo() 的调用与abfmt 周围的捕获组以及可变参数... 匹配?

如果可能的话,我还希望解决方案完全不依赖于参数的数据类型。

我目前的尝试是:foo(\(.*\),\s*\n*\s*\(.*\),\s*\n*\s*\(.*\),\s*\n*\s*\(.*\));

但由于最后的 \(.*\) 不匹配带有通配符的换行符,它会中断。

【问题讨论】:

  • 如果唯一的问题是\(.*\)不匹配换行符,用\(\_.\{-}\)替换它
  • 您应该为这个问题提供更多背景信息。如果是一次性的项目变更,一般不值得构建一个详尽的解决方案;只需浏览项目并手动编辑foo 的所有用途。如果需要重复执行(为什么?),您无法正确使用正则表达式,因为它们无法匹配 C 语法的所有可能性(例如带有内部括号和逗号的参数)。预处理器宏可能可以完成这项工作;你可以使用#define foo(a, b, ...) bar((a), (b), c, __VA_ARGS__)
  • 一般来说,处理所有可能的变体是非常棘手的:foo(hangup(12+catz, 15/dogz), window_size(scr, subwin), "foo(a, b, fmt, arg1, 'd')", atan2(dogz, sqrt(b * b + c * c))) 或任何类似的东西如果你尝试用正则表达式来做这件事会让你大吃一惊。我什至没有尝试将 cmets 嵌入到通话中。

标签: c regex vim


【解决方案1】:

最佳解决方案:使用实际的重构工具。

Vim 中的最佳时间/精力折衷方案:

  1. 在整个项目中搜索foo() 调用,例如:

    :grep -r foo\( **/*.{c,h}
    

    这会使用给定文件中出现foo( 的每一行的条目填充快速修复列表。

  2. 在每场比赛中用bar替换foo,并确认:

    :cdo s/foo(/bar(/gc
    

    这会在 quickfix 列表中的每个条目上运行替换,因此在出现 foo( 的每一行上运行。使用/c 标志,您会收到一个提示,要求您确认替换。有点行人不过:

    • 它让您可以控制重构,
    • 它也适用于 cmets,
    • 它不需要太多的正则表达式预先工作,即:您现在就完成了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-11-16
    • 2017-12-01
    • 2016-09-12
    • 1970-01-01
    相关资源
    最近更新 更多