如何将 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?
多年来我一直使用 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?