用于捕获最后一次出现的模式的正则表达式
Regular expression to capture last occurrence of a pattern
我为最后一次尝试了几种方法,但它们都不起作用。以下是我的情况,
abc def = ghi
abc def ghi = jkl
abc def ghi=jkl mno
对于第一行,我的捕获目标是"def"。对于第二行,我的捕获目标是"ghi",对于第三行,我的捕获目标是"ghi"。目标可以口头表达为"the last occurrence of word before equal sign".
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=]*=
更准确地匹配您的 "verbal expression"。例如,它将匹配 abc
in abc !@# = def
.
\b
在 \w
和 \W
之间匹配。
\w
匹配一个非单词字符。
\W
匹配非单词字符的字符。
\s
匹配空白字符。
[^\w=]
匹配 =
. 以外的非单词字符
您实际上也不需要正则表达式。您可以:
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
杰克的回答可能是最好的,但我无法理解它是如何工作的。我喜欢把事情分解成更小的块。
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 = ;
$right_side = ;
}
# 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];
}
我为最后一次尝试了几种方法,但它们都不起作用。以下是我的情况,
abc def = ghi
abc def ghi = jkl
abc def ghi=jkl mno
对于第一行,我的捕获目标是"def"。对于第二行,我的捕获目标是"ghi",对于第三行,我的捕获目标是"ghi"。目标可以口头表达为"the last occurrence of word before equal sign".
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=]*=
更准确地匹配您的 "verbal expression"。例如,它将匹配 abc
in abc !@# = def
.
\b
在\w
和\W
之间匹配。\w
匹配一个非单词字符。\W
匹配非单词字符的字符。\s
匹配空白字符。[^\w=]
匹配=
. 以外的非单词字符
您实际上也不需要正则表达式。您可以:
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
杰克的回答可能是最好的,但我无法理解它是如何工作的。我喜欢把事情分解成更小的块。
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 = ;
$right_side = ;
}
# 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];
}