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

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

#!/usr/local/bin/perl
use warnings;
use 5.014;

my $string = '12 34 56 78 90';

say $string =~ s/(?:(\S+)\s){2}/$1,$2,/r;
# Use of uninitialized value $2 in concatenation (.) or string at ./so.pl line 7.                                                           
# 34,,56 78 90 

С @LAST_MATCH_START а также @LAST_MATCH_END это работает*, но линия становится слишком длинной. Не работает, посмотрите на ответ TLP.

*The proof of the pudding is in the eating не всегда прав.

say $string =~ s/(?:(\S+)\s){2}/substr( $string, $-[0], length($-[0]-$+[0]) ) . ',' . substr( $string, $-[1], length($-[1]-$+[1]) ) . ','/re;
# 12,34,56 78 90

2 ответа

Решение

Вы не можете получить доступ ко всем предыдущим значениям первой группы захвата, только последнее значение (или текущее значение в конце матча, как вы его видите) будет сохранено в $1 (если вы не хотите использовать (?{ code }) взломать).

Для вашего примера вы можете использовать что-то вроде:

s/(\S+)\s+(\S+)\s+/$1,$2,/

Утверждение, что вы говорите "работает", содержит ошибку.

length($-[0]-$+[0]) 

Всегда будет возвращать длину отрицательной длины вашего регулярного выражения. Число $-[0] а также $+[0] смещение начала и конца первого совпадения в строке соответственно. Поскольку длина совпадения составляет три символа (в данном случае), начальный минус конечный сдвиг всегда будет -3, а также length(-3) всегда будет 2.

Итак, что вы делаете, берете первые два символа матча 12 34и первые два символа матча 34 и объединяя их с запятой в середине. Это работает по совпадению, а не из-за захвата групп.

Звучит так, как будто вы просите нас решить проблемы, которые у вас есть с вашим решением, а не спрашивать нас о главной проблеме.

Другие вопросы по тегам