4

我正在尝试从最后一个壁橱匹配到最后一个词。

例如,最接近狗的 b

“abcbdog”

应该是“bdog”

但相反,我得到了“bcbdog”

我怎样才能只匹配“dog”之前的最后一次出现的“b”

这是我当前的正则表达式:

/b.*?dog/si

谢谢!

4

6 回答 6

7

正则表达式想要从左到右,但你想从右到左,所以只需反转你的字符串,反转你的模式,然后反转匹配:

my $search_this  = 'abcbdog';
my $item_name    = 'dog';
my $find_closest = 'b';

my $pattern = reverse($item_name)
            . '.*?'
            . reverse($find_closest);

my $reversed     = reverse($search_this);
$reversed        =~ /$pattern/si;
my $what_matched = reverse($&);
print "$what_matched\n";
# prints bdog
于 2011-10-29T19:33:39.433 回答
4

试试这个:

/b[^b]*dog/si

Match b,然后是不是 a 的任何东西b(包括什么都没有),然后是dog.

于 2011-10-29T19:28:19.583 回答
1

蒂姆托迪:

此方法甚至可以通过字符串找到多个匹配项,或者如果开始或结束词更常见,则可以进行优化。编辑:现在使用零宽度匹配来避免删除然后添加开始和结束字符串。

#!/usr/bin/env perl

use strict;
use warnings;

use v5.10; #say

my $string = 'abcbdog';
my $start = 'b';
my $end = 'dog';

my @found = 
  grep { s/(?<=$end).*// } 
  split( /(?=$start)/, $string );

say for @found;
于 2011-10-29T22:15:39.773 回答
0

当您还不知道 dog 之前的最后一个字符是什么时,这很有效:

my $str = 'abcbdog';

my @r = $str =~ /(.dog)/;

print @r;

打印 bdog

于 2011-10-30T19:11:35.037 回答
0

如果您只是想将最接近的“b”与“狗”(包括狗)进行匹配,那么接受的答案似乎有点复杂,您只需要在您正在寻找贪婪的术语之前进行匹配。例如:

# First example
my $string1 = 'abcbdog';
if ( $string1 =~ /.+(b.*dog)/ ) {
    print $1;
    # Returns 'bdog'
}

# Second example, different string, same regex.
my $string2 = 'abcbmoretextdog';
if ( $string2 =~ /.+(b.*dog)/ ) {
    print $1;
    # Returns 'bmoretextdog'
}

还是我错过了什么?如果您想更改捕获的字符串以匹配您想要的内容,只需移动括号即可。

于 2011-11-03T21:27:21.530 回答
0

试试这个代码:

~/.* b.*?dog/si
于 2014-04-30T22:30:20.447 回答