Страницы

Поиск по вопросам

пятница, 21 июня 2019 г.

регулярное выражение, удаляющее комментарии. Perl

Задание: есть текст, допустим abc/*de/*f*/m*/x с комментариями, которые нужно удалить регулярным выражением, причем, если в комментарии есть вложенный комментарий, то сначала надо удалить его.
У меня получилось что-то такое:
while ($string =~ m|/\*(.*?)\*/|) { $string =~ s|(/\*((?!(.*?/\*).*?).*?)\*/.*?)|$_|; print ""$string
; }
Получим:
abc/*de/*f*/m*/x abc/*dem*/x abcx
И все вроде работает хорошо, но если в примере будут идти два комментария подряд, допустим теперь строка abc/*de/*f*/*/x, то программа зациклится.
Подскажите, как можно решить эту проблему.


Ответ

$string="abc/*def/*gh/*j*/ik*/lmn*/opq/*r/*st*/uvw*/xyz"; print "$string

"; while($string=~m|/\*.*?\*/|) { # До тех пор пока комментарии остались $string=~s|/\*((?!.*?(?0)).*?)\*/||; # Вырезаем один print "$string
"; }
Результат:
abc/*def/*gh/*j*/ik*/lmn*/opq/*r/*st*/uvw*/xyz
abc/*def/*gh/*j*/ik*/lmn*/opq/*ruvw*/xyz abc/*def/*gh/*j*/ik*/lmn*/opqxyz abc/*def/*ghik*/lmn*/opqxyz abc/*deflmn*/opqxyz abcopqxyz
Смысл вырезающей регулярки:
/\* # Комментарий открылся ( # Выделяющая группа (?!.*?(?0)) # Внутри которой не содержится еще одно выражение .*? ) \*/ # Комментарий закрылся
Основа в ссылке (?0), которая на свое место подставляет текст всего выражения целиком, рекурсивно.

Комментариев нет:

Отправить комментарий