Как я могу извлечь совпадения из оператора сопоставления Perl в переменные?

Если у меня есть оператор сопоставления, как сохранить части строк, записанных в круглых скобках в переменных вместо использования $1, $2 и т.д.?

... = m/stuff (.*) stuff/;

Что происходит слева?

Ответ 1

Трюк заключается в том, чтобы сделать m//работать в контексте списка, используя назначение списка:

 ($interesting) = $string =~ m/(interesting)/g;

Это можно аккуратно расширить, чтобы захватить больше вещей, например:

 ($interesting, $alsogood) = $string =~ m/(interesting) boring (alsogood)/g;

Ответ 2

Используйте конструкцию брекетинга (...) для создания буфера захвата. Затем используйте специальные переменные $1, $2 и т.д. Для доступа к захваченной строке.

if ( m/(interesting)/ ) {
    my $captured = $1;
}

Ответ 3

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

Чтобы извлечь что-то интересное, вам также необходимо каким-то образом привязать бит, который вам интересен при извлечении.

Итак, с вашим примером, сначала убедитесь, что строка ввода соответствует нашему выражению, а затем извлеките бит между двумя "скучными" битами:

$input = "boring interesting boring";
if($input =~ m/boring (.*) boring/) {
    print "The interesting bit is $1\n";
}
else {
    print "Input not correctly formatted\n";
}

Ответ 4

Вы можете использовать именованные буферы захвата:

if (/ (?<key> .+? ) \s* : \s* (?<value> .+ ) /x) { 
    $hash{$+{key}} = $+{value};
}

Ответ 5

@strings идет слева и будет содержать результат, затем идет строка ввода $input_string. Не забудьте флаг g для соответствия всех подстрок.

my @strings=$input_string=~m/stuff (.*) stuff/g;

Ответ 6

$& - строка, сопоставляемая последним успешное совпадение шаблонов (не считая любые совпадения, скрытые в блоке или eval(), заключенный в текущий БЛОК).

#! /usr/bin/perl

use strict;
use warnings;

my $interesting;
my $string = "boring interesting boring";
$interesting = $& if $string =~ /interesting/;