捕获最后一次出现的模式的正则表达式
我尝试了几种最后一次出现的方式,但它们不起作用。以下是我的情况,捕获最后一次出现的模式的正则表达式
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 [email protected]# = def
中匹配abc
。
-
\b
一个\w
和\W
之间的匹配。 -
\w
匹配一个非单词字符。 -
\W
匹配不是单词字符的字符。 -
\s
匹配一个空白字符。 -
[^\w=]
与除=
以外的非单词字符匹配。
你也不需要正则表达式。您可以:
-
split
上/\s*=\s*/
- 抢所得数组的第一个元素
-
split
(即所有之前等号(含空格剥离右端)的东西)的第一个字符串从步骤2的/\s+/
- 字符串取所得阵列的最后一个元素从步骤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
杰克的回答可能是最好的,但我不能换我围绕它是如何工作的头。我喜欢把事情分解成更小的块。
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 "$last\n";
}
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分割的数组中获取索引元素 - 即split(/ \ s * = \ s * /,$ str)[0]'是一个语法错误。所以,你必须将'split'包装在括号中,如下所示:'(split(/ \ s * = \ s * /,$ str))[0]'。其余部分将该元素分割到'/ \ s + /'上,并抓取该结果数组的最后一个元素。希望能够解决问题。你的写作也很好。 :) – 2015-02-06 18:36:42
这里预见的唯一功能是减慢匹配。 – ikegami 2015-02-05 17:51:11
我使用后视,因为我认为它是从“=”号后面找到最接近的单词。但后视对我来说不起作用。 – Allen 2015-02-06 08:15:13
@Allen,你不能在这里使用lookbehind,因为lookbehinds匹配的长度必须独立于输入。即使它确实有效,使用lookbeind也会让事情变得缓慢。我很失望你接受了这个不合理的解决方案 – ikegami 2015-02-06 16:58:50