![使用正则表达式在函数名称之前提取函数字符串](https://linux22.com/image/198603/%E4%BD%BF%E7%94%A8%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%9C%A8%E5%87%BD%E6%95%B0%E5%90%8D%E7%A7%B0%E4%B9%8B%E5%89%8D%E6%8F%90%E5%8F%96%E5%87%BD%E6%95%B0%E5%AD%97%E7%AC%A6%E4%B8%B2.png)
我想要一个正则表达式来搜索类似的内容:
package_name.some_function_name.foo()
这将是一行的一部分,并且会提取some_function_name
但它应该也可以用于以下内容:
if(some_function_name.foo()){
即package_name
缺失
我试过:
git grep -h foo | perl -pe 's/.*\w.*(package_name[.])?(.*_.*)[.]foo.*/$2/'
但不起作用
如果除此之外还有其他perl
更好的方法,例如 sed 我也同意
答案1
您的.*\w.*(package_name[.])?(.*_.*)[.]foo.*
正则表达式匹配包含单词字符的行,然后匹配 a _
(我什至没有提及,package_name.
因为它是可选的),然后匹配.foo
。并捕获最后一次出现 之前的最后一个字符之前的最后一个单词字符和 that$2
之间的内容。_
.foo
.foo
例如,在
asd().x_y + x.foo() + blah_x++ - _x.foobar
^^^^^^^^
然后,s///
将用整行替换那些匹配的行(因为正则表达式匹配整行内容),但保留其他行不变。
相反,你可以这样做:
perl -lne 'print for /(\w+)\.foo\(/g'
它提取每次出现之前的单词字符序列,.foo(
前面至少有一个单词字符。
something.
如果您希望仅当something
is时才允许该单词字符序列前面带有 a package_name
,您可以这样做:
perl -lne '
while (/(\w+\.)?(\w+)\.foo\(/g) {
print $2 if !$1 || $1 eq "package_name.";
}'
或者,也排除other.package_name.foo()
:
perl -lne '
while (/((?:\w+\.)*)(\w+)\.foo\(/g) {
print $2 if !$1 || $1 eq "package_name.";
}'
答案2
假设您正在查找 before 的字符串.foo()
,您可以尝试:
sed 's/^.*\W\(\w*\)\.foo().*$/\1/g'
解释:
- 该符号
\w
是同义词[_[:alnum:]]
- 该符号
\W
是同义词[^_[:alnum:]]
因此,我们要查找之前的部分,该部分仅由和字符.foo()
组成,并且前面有字符。我们只用这部分替换整条生产线。alphanumeric
_
non-alphanumeric
警告
如果some_function_name.foo()
在同一行出现两次,则只会捕获第一个实例。
如果你想确保你能抓住全部对于这些模式,即使它们在同一行出现两次,您也可以使用:
grep -Po '\w*(?=\.foo\(\))'
解释:
来自 man grep:
-P,--perl-正则表达式
将该模式解释为与 Perl 兼容的正则表达式 (PCRE)。这是实验性的并且grep -P可能会警告未实现的功能。
-o,--仅匹配
仅打印匹配行的匹配(非空)部分,每个此类部分位于单独的输出行上。
的部分(?=\.foo\(\))
称为Lookahead
,它允许您从模式中删除部分匹配文本。所以在这种情况下,它将来自.foo()
于模式。