Регулярные выражения Perl и их применение


Ретроспективная проверка


Имеется аналогичная возможность также "заглянуть назад":

(?<= шаблон )

Это условие истинно, если перед текущей позицией имеется текст, совпадающий с шаблоном. Но не надо думать, что проверка здесь идет справа налево. Например:

$_='abcd'; print "1\n" if /ab(?<=(ab))/; print $1;

В результате получим вывод

1 ab

Как видим, захват текста в этих якорях также происходит.

Негативная ретроспективная проверка задается выражением

(?<! шаблон )

и требует, чтобы непосредственно перед текущей позицией не было текста, соответствующего данному шаблону.

Но в ретроспективных проверках шаблон уже не может быть каким угодно, а должен соответствовать только определенному числу символов. Механизм поиска должен по этому шаблону определить длину текста, которому он может соответствовать, и искать левее текущей позиции на число символов, с которыми этот шаблон может совпасть.

Иначе пришлось бы искать с начала всего текста, а это большие непроизводительные затраты времени. Поэтому шаблон не может содержать квантификаторы переменной длины, а все альтернативы в альтернативных конструкциях должны совпадать с текстом одной и той же длины. Вот примеры ошибок:

(?<=\w+) (?<=\w{1,2}) (?<=\w{3}|abcd)

В первых двух случаях имеем переменную длину квантификатора, а в последнем - разную длину альтернатив.

В качестве примера использования этих якорей рассмотрим задачу разделения разрядов числа запятыми. Большие числа удобнее воспринимать, когда они поделены запятыми по три разряда: 12,345,678. Хотя тройки разрядов отсчитываются справа, а механизм поиска просматривает текст слева, эту техническую сложность нетрудно обойти. Сформулируем условие вставки запятой так: запятая вставляется в позицию, слева от которой имеется цифра, а справа - произвольное ненулевое число групп из трех цифр и далее не стоит цифра. Вот программа, которая моделирует этот пример:

$_='number 1: 12345678 number 2: 98765432154321'; s/(?<=\d)(?=(?:\d{3})+(?!\d))/,/g; print $_;

На печать выведется

number 1: 12,345,678 number 2: 98,765,432,154,321




- Начало -  - Назад -  - Вперед -



Книжный магазин