Perl регулярное выражение соответствует - PullRequest
4 голосов
/ 29 октября 2011

Я пытаюсь найти соответствие от последнего пункта шкафа до последнего слова.

Например, ближайший б к собаке

"abcbdog"

Должно быть "bdog"

Но вместо этого я получаю "bcbdog"

Как я могу сопоставить только с последнего вхождения "b" перед "собакой"

Вот мое текущее регулярное выражение:

/b.*?dog/si

Спасибо!

Ответы [ 6 ]

7 голосов
/ 29 октября 2011

Регулярные выражения хотят идти слева направо, но вы хотите идти справа налево, поэтому просто переверните строку, измените шаблон и измените совпадение:

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
4 голосов
/ 29 октября 2011

Попробуйте это:

/b[^b]*dog/si

Совпадение b, затем все, что не является b (включая ничего), а затем dog.

1 голос
/ 30 октября 2011

TIMTOWTDI:

Этот метод может даже найти несколько совпадений в строке или может быть оптимизирован, если начальные или конечные слова будут более распространенными. Редактировать: Теперь используются совпадения нулевой ширины, чтобы избежать удаления, а затем добавления начальной и конечной строк.

#!/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;
0 голосов
/ 01 мая 2014

Попробуйте этот код:

~/.* b.*?dog/si
0 голосов
/ 04 ноября 2011

Принятый ответ кажется немного сложным, если вы просто пытаетесь сопоставить ближайшую букву «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'
}

Или я что-то упустил?Если вы хотите изменить захваченную строку, чтобы она соответствовала тому, что вы хотите, просто сдвиньте скобки.

0 голосов
/ 30 октября 2011

, когда вы не знаете, какой последний символ перед собакой, это просто работает:

my $str = 'abcbdog';

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

print @r;

выводит bdog

...