从grep Perl样式的正则表达式语法到实际的Perl正则表达式模式匹配

时间:2014-03-21 16:49:10

标签: regex perl grep

我无法将grep中使用的Perl正则表达式转换为perl语法

#/bin/bash
string="Last logical block address=936640511 (0x37d3ffff), Number of blocks=936640512"
echo $string | grep -Po '(?<=blocks=)[^$]*'

使用perl,我无法成功

#!/usr/bin/perl
my $string="Last logical block address=936640511 (0x37d3ffff), Number of blocks=936640512";
my ($blocks) = $string =~ m/(?<=blocks=)[^$]*/;
print $blocks;

如果我使用正确的正则表达式,请提供建议。

2 个答案:

答案 0 :(得分:5)

列表上下文中的匹配运算符返回捕获的文本(如果有),因此您需要做的就是在要返回的位周围添加捕获(parens)。

my ($blocks) = $string =~ /(?<=blocks=)([^$]*)/;
print "$blocks\n";

后面的观点只会让你失望。

my ($blocks) = $string =~ /blocks=([^$]*)/;
print "$blocks\n";

我们应该检查一下匹配是否成功。

if ( my ($blocks) = $string =~ /blocks=([^$]+)/ ) {
    print "$blocks\n";
}

但是我很困惑为什么你要匹配美元符号以外的字符。你可能想要匹配换行符以外的字符。

if ( my ($blocks) = $string =~ /blocks=([^\n]+)/ ) {
    print "$blocks\n";
}

鉴于您没有使用/s,也可以写

if ( my ($blocks) = $string =~ /blocks=(.+)/ ) {
    print "$blocks\n";
}

就个人而言,我使用

if ( my ($blocks) = $string =~ /blocks=(\S+)/ ) {
    print "$blocks\n";
}

要获得所有匹配,只需使用/g

for my $blocks ( $string =~ /blocks=(\S+)/g ) {
    print "$blocks\n";
}

答案 1 :(得分:1)

[^$]模式匹配“文字$以外的任何内容”,而不是您想要的字符串结尾。

请改为尝试:

if ($str =~ m/(?<=blocks=)(.*)$/)
{
    my $blocks = $1;
    print $blocks;
}

您还可以打印$&,这是与最后匹配的字符串对应的特殊变量(man perlvar)。然后,您无需使用()捕获或$1