使用grep,vim的grep或其他unix shell命令,我想在大型cpp文件中找到包含特定单词的函数.
在我正在处理的文件中,我正在查找的是缩进行,相应的函数头是从位置0开始并且不是'{'的缩进行上方的第一行.
例如,在以下代码段中搜索JOHN_DOE
int foo ( int arg1 )
{
/// code
}
void bar ( std::string arg2 )
{
/// code
aFunctionCall( JOHN_DOE );
/// more code
}
Run Code Online (Sandbox Code Playgroud)
应该给我
void bar ( std::string arg2 )
Run Code Online (Sandbox Code Playgroud)
我希望在grep/vim/unix shell脚本中捕获的算法可能最好使用缩进和格式化假设,而不是尝试解析C/C++.
谢谢你的建议.
据我所知,这是不可能的。原因如下:
首先,你必须跨线搜索。没问题,在 vim 中向字符类添加 _ 会告诉它包含新行。因此 {_.*} 将匹配多行括号之间的所有内容。
所以现在你需要匹配函数头的任何模式(即使你让它工作也很脆弱),然后,这就是问题,无论它和你的搜索字符串之间有什么行,最后匹配你的搜索字符串。所以你可能有一个像这样的正则表达式
/^\(void \+\a\+ *(.*)\)\_.*JOHN_DOE
Run Code Online (Sandbox Code Playgroud)
但是当 vim 第一次找到函数头时,它就会开始匹配。然后它匹配每个字符,直到找到 JOHN_DOE。其中包括文件中的所有函数头。
所以问题是,据我所知,没有办法告诉 vim 匹配除了这个正则表达式模式之外的每个字符。即使有,正则表达式也不是完成这项工作的工具。这就像用锤子打开啤酒一样。我们应该做的是编写一个简单的脚本来为您提供这些信息,我已经做到了。
fun! FindMyFunction(searchPattern, funcPattern)
call search(a:searchPattern)
let lineNumber = line(".")
let lineNumber = lineNumber - 1
"call setpos(".", [0, lineNumber, 0, 0])
let lineString = getline(lineNumber)
while lineString !~ a:funcPattern
let lineNumber = lineNumber - 1
if lineNumber < 0
echo "Function not found :/"
endif
let lineString = getline(lineNumber)
endwhile
echo lineString
endfunction
Run Code Online (Sandbox Code Playgroud)
这应该会给你想要的结果,并且比克苏鲁本人口中吐出的正则表达式更容易共享、调试和重新利用。