С помощью конструкции /\G шаблон /gc можно делать лексический анализ текста, производя извлечение из него нужных фрагментов один за другим, без пропусков. Это учебный пример, который показывает принцип разбора:
my $text='123 234 345 456'; while ($text =~ /\d+/g) { print "Найдено число $&\npos=".pos($text)."\n" }
На печати увидим:
Найдено число 123 pos=3 Найдено число 234 pos=7 Найдено число 345 pos=11 Найдено число 456 pos=15
Отпечатаются позиции за каждым найденным числом.
Предположим, что мы делаем разбор текста на имена, которые состоят из латинских букв, чисел и символов перевода строк. Мы должны последовательно извлекать из текста эти объекты, называть и выводить их. Если встречается что-то, что не соотвтетствует синтаксису ни одного объекта, то это будет называться unknown (неизвестно). Регулярное выражение будет начинаться с \G и представлять собой высокоуровневую конструкцию выбора:
$_=<<EOF; 123 abc -234 def \$\@ xyz EOF while (/\G (?:(?>[\000-\011\013-\040]+)| # все от \0 до пробела кроме \n (\b(?>[a-zA-Z]+)\b)(?{ print "Name: $^N\n" })| # имя ((?>[+-]?)(?>\d+)\b)(?{ print "Number: $^N\n" })| # число (\n)(?{ print "Newline:\n" })| # \n ((?>\S+))(?{ print "Unknown: $^N\n" }) # все остальное )/gx) {}
Чтобы отделить первую альтернативу выбора от \G, необходимо всю конструкцию выбора взять в скобки. На печать выйдет
Number: 123 Name: abc Newline: Number: -234 Name: def Newline: Unknown: $@ Name: xyz Newline:
В этом примере обратите внимание на то, что ветка \S+ для unknown поставлена последней, иначе разбор получился бы некорректным.
Не обязательно все шаблоны хранить в одной большой конструкции выбора, можно делать разбор текста по нескольким регулярным выражениям, но тогда надо использовать модификатор gc. Вот упрощенный пример программы проверки кода HTML с проверкой правильности закрытия тега A:
#!/usr/bin/perl -w use strict; use bytes; use locale;
$_=<<EOF; <html> <body> <слово1 слово2 1234> <a href="http://www.intuit.ru">Это ссылка</a> </body> </html> EOF