Вы застряли, если не можете убедить тех, кто контролирует код, который вы используете, в его обобщение. Хорошей новостью является то, что вам нужно только немного больше, возможно
if (my @fields = $_ =~ /$pat/) {
$req_value = join " " => grep defined($_), @fields;
}
Это работает, потому что успешное совпадение регулярного выражения в контексте списка возвращает все захваченные подстроки, , т.е. , $1
, $2
, $3
и т. Д., В зависимости от ситуации.
С одним рисунком,
qr/(\d+(?:[-.]\w+)*)(?:.*(SMP))?/
код выше дает 2.6.9-78.1.6.ELsmp SMP
и 2.6.9-78.0.5.ELsmp
in $req_value
. grep defined($_)
отфильтровывает перехваты для неиспользованных подшаблонов. Без этого вы получите предупреждения с неопределенным значением для случая без SMP.
Недостатком является то, что каждое регулярное выражение необходимо будет пересмотреть, чтобы убедиться, что все группы захвата действительно должны войти в $req_value
. Например, скажем, кто-то использует шаблон
qr/(XYZ) OS (version \d+|v-\d+)/
Как и сейчас, только XYZ будет входить в $req_value
, но использование приведенного выше обобщения также будет включать номер версии. Если это нежелательно, регулярное выражение должно быть
qr/(XYZ) OS (?:version \d+|v-\d+)/
потому что (?:...)
не захватывает (то есть, он не выдает $2
для шаблона выше): это только для группировки.