Как убрать захват из произвольно вложенных подгрупп в строке регулярного выражения Perl? Я хотел бы вложить любое регулярное выражение в обволакивающее выражение, которое охватывает под-регулярное выражение как целую сущность, а также статически известные последующие группы. Нужно ли вручную преобразовывать строку регулярного выражения в использование всех не захватывающих групп (?:)
(и надеюсь, что я не ошибаюсь), или существует механизм Perl для регулярных выражений или библиотек, обеспечивающий это?
# How do I 'flatten' $regex to protect $2 and $3?
# Searching 'ABCfooDE' for 'foo' OK, but '((B|(C))fo(o)?(?:D|d)?)', etc., breaks.
# I.E., how would I turn it effectively into '(?:(?:B|(?:C))fo(?:o)?(?:D|d)?)'?
sub check {
my($line, $regex) = @_;
if ($line =~ /(^.*)($regex)(.*$)/) {
print "<", $1, "><", $2, "><", $3, ">\n";
}
}
Приложение: Я смутно осведомлен о $&
, $`
и $'
, и мне посоветовали избегать их, если это возможно, и у меня нет доступа к ${^PREMATCH}
, ${^MATCH}
и ${^POSTMATCH}
в моей среде Perl 5.8. Приведенный выше пример можно разбить на 2/3 фрагментов, используя такие методы, и в более сложных реальных случаях это можно было бы повторить вручную, но я думаю, что я хотел бы получить общее решение, если это возможно.
Принятый ответ: То, что я желал, существовало и, на удивление (по крайней мере для меня), не существует, является инкапсулирующей группой, которая делает ее содержимое непрозрачным, так что последующие позиционные обратные ссылки рассматривают содержимое как единый объект ссылки на имена разграничены. gbacon имеет потенциально полезный обходной путь для Perl 5.10+, а FM показывает ручной итерационный механизм для любой версии, которая может выполнить то же самое эффект в определенных случаях, но j_random_hacker называет это тем, что не существует реального языкового механизма для инкапсуляции подвыражений.