如何将 git grep 与正则表达式一起使用?

How can I use git grep with regular expressions?

多年来我一直使用 git grep 来搜索固定字符串,但很少用它来进行正则表达式搜索。

我在代码中有一些地方带有非本地化字符串。例如:

   JLabel label =  buildLabel("Alphabet");

在这种情况下 buildLabel() 是一个继承的实用方法。还有buildBoldLabel()buildMultiLineLabel()buildTextArea().

所以我想在我的代码中搜索这些方法的使用,而不查找本地化字符串。正确的调用应该是:

   JLabel label =  buildLabel(getString("Alphabet"));

我非常熟悉正则表达式,我看到 git grep 支持 Perl 字符 类。所以我认为这很容易:

$ git grep -P "buildLabel(\"\w+\")"

这个returns没有结果。所以我在没有 Perl 扩展的情况下尝试了它。

$ git grep "buildLabel(\"[a-zA-Z_]+\")"

仍然...没有结果。我确认我可以使用固定字符串进行搜索。

$ git grep "buildLabel(\"Alphabet\")"

那返回了我已知存在的代码中的实例。然而...

$ git grep -P "buildLabel(\"Alphabet\")"

Returns 没有结果。

我也尝试更改引号字符并得到相同的结果。

$ git grep -P 'buildLabel("\w+")' ...没有结果

$ git grep -P 'buildLabel("Alphabet")' ...没有结果

$ git grep 'buildLabel("Alphabet")' ... 1 个预期结果

我试过 Linux,结果相同。

更新:

感谢@wiktor-stribiżew 评论说使用 PCRE 时需要转义括号(我总是对此感到困惑)。

$ git grep -P 'buildLabel\("\w+"\)' ... returns 1 个预期结果。

但是,为什么这些不起作用?

$ git grep 'buildLabel("[a-zA-Z_]+")'

$ git grep 'buildLabel\("[a-zA-Z_]+"\)'

$ git grep 'buildLabel\("[a-zA-Z_][a-zA-Z_]*"\)'(如果 + 未实现)


那么我在 git grep 上做错了什么?还是坏了?

仅供参考:我在 macOS Big Sur 上使用来自 Homebrew 的 git 版本 2.35.1。

正则表达式与固定字符串搜索

请参考git grep help:

-G
--basic-regexp
Use POSIX extended/basic regexp for patterns. Default is to use basic regexp.

因此,默认情况下,git grep 将模式字符串视为 POSIX BRE 正则表达式,而不是固定字符串

要使 git grep 将模式视为固定字符串,您需要 -F:

-F
--fixed-strings
Use fixed strings for patterns (don’t interpret pattern as a regex).

正则表达式问题

您可以使用 -P 选项启用 PCRE 正则表达式语法,在这种情况下您应该参考 PCRE documentation.

在你的 git grep -P "buildLabel(\"\w+\")" 中,括号必须被转义才能匹配为文字括号,即它应该是 git grep -P "buildLabel\(\"\w+\"\)".

git grep 'buildLabel("[a-zA-Z_]+")' 中,您使用的是 POSIX BRE regex,并且 + 被解析为文字 + 字符,而不是 one 或more 量词。不过,您可以在 POSIX BRE 中使用 git grep 'buildLabel("[a-zA-Z_]\{1,\}")'。如果它是 GNU grep,您可以使用 git grep 'buildLabel("[a-zA-Z_]\+")'(不确定它是否适用于 git)。

git grep 'buildLabel\("[a-zA-Z_]+"\)' 不起作用,因为 \(...\)(转义的一对括号)定义了一个 捕获组 ,因此不匹配文字括号。

git grep -e 'buildLabel\("[a-zA-Z_][a-zA-Z_]*"\)'与POSIX BRE相同,要使其成为POSIX ERE,需要使用-E选项,git grep -E 'buildLabel\("[a-zA-Z_][a-zA-Z_]*"\)'。或者 git grep -E 'buildLabel\("[a-zA-Z_]+"\)',未转义的 + 是 POSIX ERE 中的量词。

另外,参见 What special characters must be escaped in regular expressions?