捕获模式最后一次出现的正则表达式



我尝试了几种方法来解决上次出现的问题,但都不起作用。以下是我的案例,

abc def = ghi
abc def ghi = jkl
abc def ghi=jkl mno

对于第一行,我的捕获目标是"def"。第二行,我的捕获目标是"ghi",第三行,我捕获的目标是"ghi"。目标可以口头表达为"等号前单词的最后一次出现"。

Perl的正则表达式应该是什么样子?

您可以使用此模式

(w+)(?=s*=)

演示

(               # Capturing Group (1)
  w            # <ASCII letter, digit or underscore>
  +             # (one or more)(greedy)
)               # End of Capturing Group (1)
(?=             # Look-Ahead
  s            # <whitespace character>
  *             # (zero or more)(greedy)
  =             # "="
)               # End of Look-Ahead

b(w+)s*=对于您的示例就足够了。它匹配一个单词,可选地紧跟空白,紧跟=b减少了回溯。

b(w+)[^w=]*=更精确地匹配你的"言语表达"。例如,它将与abc !@# = def中的abc相匹配。

  • CCD_ 7在CCD_ 8和CCD_
  • w匹配非单词字符
  • W匹配的字符不是单词字符
  • s与空白字符匹配
  • CCD_ 13匹配除CCD_ 14之外的非单词字符

Jack的答案可能是最好的,但我无法理解它是如何工作的。我喜欢把东西分解成小块。

use warnings;
use strict;
my @strings = ( "abc def = ghi",
                "abc def ghi = jkl",
                "abc def ghi=jkl mno"
                );
#
foreach (@strings) {
    my $last = get_last($_);
    print "$lastn";
}
sub get_last {
    my $string = shift;
    # group things as left side or right side
    my $left_side;
    my $right_side;
    if ($string =~ /(.*)=(.*)/) {
        $left_side = $1;
        $right_side = $2;
    }
    # split things according to whitespace and store in an array
    my @left_side = split (/s+/, $left_side);
    # return the last element of that array
    return $left_side[-1];
}

您也不需要正则表达式。您可以:

  • split /s*=s*/上的第一个字符串
  • 获取结果数组的第一个元素(即等号之前的所有内容(右端去掉空白))
  • split来自/s+/上步骤2的字符串
  • 取步骤3中得到的数组的最后一个元素

换句话说:

use strict;
use warnings;
my $str1 = "abc def = ghi";
my $str2 = "abc def ghi = jkl";
my $str3 = "abc def ghi=jkl mno";
sub grab_target{
    my $str = shift;
    return (split(/s+/, (split(/s*=s*/, $str))[0]))[-1];
}
foreach  my $str ($str1, $str2, $str3){
    print grab_target $str;
    print "n";
}

结果输出为:

def
ghi
ghi

最新更新