Обнаружить разницу соответствия в контексте списка с захватом против не-захвата regexp?

по данным perlretut

... в скалярном контексте, $time =~ /(\d\d):(\d\d):(\d\d)/ возвращает значение true или false. Однако в контексте списка он возвращает список сопоставленных значений (,,) .

но я не могу найти объяснение того, что возвращается в контексте списка, если шаблон соответствует, когда в регулярном выражении нет групп захвата. Тестирование показывает, что это list (1) (один элемент, целое число 1). (Вспомогательный вопрос-будет ли это всегда быть таким, где это определено?)

это делает его трудно сделать то, что я хочу:

if (my @captures = ($input =~ $regexp)) {
    furtherProcessing(@captures);
}

Я хочу furtherProcessing вызывается, если есть совпадение, с любыми захваченными группами, переданными в качестве аргументов. Проблема возникает, когда $regexp Не содержит групп захвата, потому что тогда я хочу furtherProcessing вызывается без аргументов, а не со значением 1 что и происходит в выше. Я не могу проверить на (1) как особый случай, как это

if (my @captures = ($input =~ $regexp)) {
    shift @captures if $captures[0] == 1;
    furtherProcessing(@captures);
}

потому что в случае

$input = 'a value:1';
$regexp = qr/value:(\S+)/;

есть захваченное значение в @captures это выглядит так же, как и то, что я получаю, когда $regexp соответствует, но не имеет групп захвата.

есть ли способ сделать то, что я хочу?

1 ответов


можно использовать $#+ чтобы узнать, сколько групп было в последнем успешном матче. Если это 0, то групп не было, и у вас есть (1). (Да, так будет всегда!--2--> если нет групп, как описано в perlop.)

Итак, это будет делать то, что вы хотите:

if (my @captures = ($input =~ $regexp)) {
    @captures = () unless $#+; # Only want actual capture groups
    furtherProcessing(@captures);
}

отметим, что $#+ подсчитывает все группы, независимо от того, совпадают они или нет (до тех пор, пока весь повторно сопоставлен). Итак,"hello" =~ /hello( world)?/ вернет 1 группу, даже хотя группа не совпадала (значение в @captures будет undef).