Как я могу сопоставить все, что находится после последнего появления некоторого символа в регулярном выражении perl?

Например, вернуть часть строки, которая находится после последнего x в axxxghdfx445 (должен вернуть 445 ).

16
задан Cœur 30 April 2017 в 14:43
поделиться

7 ответов

my($substr) = $string =~ /.*x(.*)/;

Из perldoc perlre:

По умолчанию количественный подшаблон является «жадным», то есть соответствует столько раз, сколько возможно (с учетом конкретного начального местоположения), пока все еще позволяя остальной части шаблона совпадать.

Вот почему . * X будет соответствовать последнему вхождению x .

19
ответ дан 30 November 2019 в 16:00
поделиться

первый ответ - хороший, но когда речь идет о "чем-то, что не содержит"... мне нравится использовать regex, который "соответствует" этому

my($substr) = $string =~ /.*x([^x]*)$/;

очень полезно в некоторых случаях

6
ответ дан 30 November 2019 в 16:00
поделиться

Еще один способ сделать это. Это не так просто, как одно регулярное выражение, но если вы оптимизируете скорость, этот подход, вероятно, будет быстрее, чем что-либо, использующее регулярное выражение, включая split .

my $s     = 'axxxghdfx445';
my $p     = rindex $s, 'x';
my $match = $p < 0 ? undef : substr($s, $p + 1);
3
ответ дан 30 November 2019 в 16:00
поделиться

Я удивлен, что никто не упомянул специальную переменную, которая делает это, $ ': « $' » возвращает все после совпавшей строки. ( perldoc perlre )

my $str = 'axxxghdfx445';
$str =~ /x/;

# $' contains '445';
print $';

Однако есть стоимость (выделено мной):

ПРЕДУПРЕЖДЕНИЕ: как только Perl увидит, что вам нужен один из $ &, "$ " или "$ '" в любом месте в программе они должны быть предоставлены для каждого сопоставления с образцом. Этот может существенно замедлить вашу программу. Perl использует тот же механизм для производят 1, 2 доллара и т. д., поэтому вы также платите цену за каждый образец, который содержит захватывающие скобки. (Чтобы избежать этой стоимости при сохранении поведение группировки, используйте расширенное регулярное выражение "(?: ...)" вместо этого.) Но если вы никогда не используете $ &, "$ " или "$ '", то шаблоны без захват круглых скобок не наказывается. Так что избегайте $ &, "$ '" и "$` ", если можно, но если нельзя (а некоторые алгоритмы действительно цените их), как только вы их использовали один раз, используйте их по своему желанию, потому что вы уже заплатили цену. По состоянию на 5.005 $ & не так дорого, как два других.

Но подождите, это еще не все! Вы получаете двух операторов по цене одного, действуйте СЕЙЧАС!

В качестве временного решения этой проблемы Perl 5.10.0 вводит "$ {^ PREMATCH}", "$ {^ MATCH}" и "$ {^ POSTMATCH}", которые эквивалентны на "$` ", $ & и" $ '", за исключением того, что они гарантированно будут определяется после успешного совпадения, которое было выполнено с помощью "/ p" (сохранить) модификатор.Использование этих переменных не влечет за собой глобальных штраф за производительность, в отличие от их эквивалентов знаков препинания, однако на компромисс, заключающийся в том, что вы должны сообщить Perl, когда вы хотите их использовать.

my $str = 'axxxghdfx445';
$str =~ /x/p;

# ${^POSTMATCH} contains '445';
print ${^POSTMATCH};

Я смиренно утверждаю, что этот маршрут самый лучший и самый простой подход в большинстве случаев, так как он не требует от вас особых действий с построением вашего шаблона, чтобы получить часть постматча, и там нет потери производительности.

3
ответ дан 30 November 2019 в 16:00
поделиться

Самым простым способом будет использование /([^x]*)$/

11
ответ дан 30 November 2019 в 16:00
поделиться

, самым простым способом является не регулярное выражение, а простое разделение ( ) и получение последнего элемента.

$string="axxxghdfx445";
@s = split /x/ , $string;
print $s[-1];
2
ответ дан 30 November 2019 в 16:00
поделиться

Регулярное выражение : /([^x]+)$/ #при условии, что x - не последний элемент строки.

1
ответ дан 30 November 2019 в 16:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: