如何使 perl 正则表达式不贪心?
How to make the perl regex not to be greedy?
我有这样的路径:
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/com.asas.gnua.feature_4.0.0
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.codehaus.jackson_1.0.0/META-INF
/nfs/usr/x86-64_linux71/gnua/4.0.0/configuration
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.easymock_2.5.1
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/org.eclipse.e4.rcp_1.6.100.v20180611-0422
我想构建一个正则表达式来捕获这些路径,因此 gnua
是第一组,4.0.0
是第二组。我试过了:
^\/nfs\/.*?\/.*?\_linux\d+\/(.*)?\/(.*)?\/.*?
但我得到 gnua/4.0.0
作为第一组,features
作为第二组。在 Perl 中如何使第一组为 gnua
而第二组为 4.0.0
?也就是说,最后的.*?
应该是features/com.asas.gnua.feature_4.0.0
.
将问号移到匹配组中。
/^\/nfs\/.*?\/.*?\_linux\d+\/(.*?)\/(.*?)\/.*?/
更改定界符可提高可读性:
m{^/nfs/.*?/.*?_linux\d+/(.*?)/(.*?)/.*?}
但是使用 ([^/]*)
通常比 (.*?)
更安全。
正如 choroba 已经指出的那样,问号 应该移到捕获组括号内。
为了方便起见,您可以定义一个包含正则表达式的字符串(如果出现这种情况,它还允许在代码的其他部分重用它)。
#!/usr/bin/env perl
#
# vim: ai ts=4 sw=4
use strict;
use warnings;
use feature 'say';
my $re = '/nfs/usr/x86-64_linux.*?/(.*?)/(.*?)/';
while( <DATA> ) {
my @arr = (,) if /$re/;
say join("\t",@arr);
}
__DATA__
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/com.asas.gnua.feature_4.0.0
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.codehaus.jackson_1.0.0/META-INF
/nfs/usr/x86-64_linux71/gnua/4.0.0/configuration
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.easymock_2.5.1
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/org.eclipse.e4.rcp_1.6.100.v20180611-0422
输出
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0
我有这样的路径:
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/com.asas.gnua.feature_4.0.0
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.codehaus.jackson_1.0.0/META-INF
/nfs/usr/x86-64_linux71/gnua/4.0.0/configuration
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.easymock_2.5.1
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/org.eclipse.e4.rcp_1.6.100.v20180611-0422
我想构建一个正则表达式来捕获这些路径,因此 gnua
是第一组,4.0.0
是第二组。我试过了:
^\/nfs\/.*?\/.*?\_linux\d+\/(.*)?\/(.*)?\/.*?
但我得到 gnua/4.0.0
作为第一组,features
作为第二组。在 Perl 中如何使第一组为 gnua
而第二组为 4.0.0
?也就是说,最后的.*?
应该是features/com.asas.gnua.feature_4.0.0
.
将问号移到匹配组中。
/^\/nfs\/.*?\/.*?\_linux\d+\/(.*?)\/(.*?)\/.*?/
更改定界符可提高可读性:
m{^/nfs/.*?/.*?_linux\d+/(.*?)/(.*?)/.*?}
但是使用 ([^/]*)
通常比 (.*?)
更安全。
正如 choroba 已经指出的那样,问号 应该移到捕获组括号内。
为了方便起见,您可以定义一个包含正则表达式的字符串(如果出现这种情况,它还允许在代码的其他部分重用它)。
#!/usr/bin/env perl
#
# vim: ai ts=4 sw=4
use strict;
use warnings;
use feature 'say';
my $re = '/nfs/usr/x86-64_linux.*?/(.*?)/(.*?)/';
while( <DATA> ) {
my @arr = (,) if /$re/;
say join("\t",@arr);
}
__DATA__
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/com.asas.gnua.feature_4.0.0
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.codehaus.jackson_1.0.0/META-INF
/nfs/usr/x86-64_linux71/gnua/4.0.0/configuration
/nfs/usr/x86-64_linux71/gnua/4.0.0/plugins/org.easymock_2.5.1
/nfs/usr/x86-64_linux71/gnua/4.0.0/features/org.eclipse.e4.rcp_1.6.100.v20180611-0422
输出
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0
gnua 4.0.0