| ||||||||||
Синтаксис Патэрна(unknown) Синтаксис патэрна - Описывает синтаксис PCRE regex.ОписаниеБиблиотека PCRE это набор функций, реализующих подстановку патэрнов регулярных выражений с использованием синтаксиса и семантики Perl 5 с незначительными отличиями (см. далее). Текущая реализация соответствует Perl 5.005. Отличия от PerlЭти отличия даны относительно Perl 5.005.
Регулярные выражения. Детали.ВведениеНиже описаны синтаксис и семантика регулярных выражений, поддерживаемых в PCRE.
Регулярные выражения описаны также в документации Perl и в некоторых других
книгах, некоторые из которых содержат копии примеров. Книга Jeffrey
Friedl'а "Mastering Regular Expressions", опубликованная
O'Reilly (ISBN 1-56592-257-3), рассматривает их в деталях.
Данное описание может служить справочником. МетасимволыМощность регулярным выражениям придаёт возможность включать в патэрн альтернативы и повторения. Они кодируются в патэрне метасимволами, которые не представляют самих себя, а интерпретируются особым образом. Имеются два различных набора метасимволов: распознаваемые в любом месте патэрна, кроме квадратных скобок,
и те, которые распознаются в квадратных скобках.
В классе символов метасимволами являются только:
backslash/обратный слэшСимвол backslash используется по-разному. Во-первых, если после него идёт неалфавитный символ, он отменяет любое специальное значение, которое символ может иметь. Такое использование обратного слэша как escape-символа применяется как внутри, так и вне классов символов. Например, если вы хотите найти совпадение с символом "*", вы записываете в патэрне "\*". Это будет работать независимо от того, может ли последующий символ интерпретироваться как метасимвол, поэтому всегда надёжнее записывать неалфавитный символ с "\", чтобы специфицировать, что он представляет сам себя. Особенно если вы хотите найти совпадение с backslash - тогда вы записываете "\\". Если патэрн компилируется с опцией PCRE_EXTENDED, то пробелы
в патэрне (кроме пробелов в классе символов) и символы между "#"
вне класса символов и следующим символом newline игнорируются. Во-вторых, backslash предоставляет способ кодирования в патэрне непечатаемых символов видимым образом. Ограничений на появление непечатаемых символов нет, за исключением двоичного нуля, который оканчивает патэрн, но если патэрн подготавливается путём редактирования текста, то обычно легче использовать одну из следующих escape-последовательностей (замен), а не бинарный символ, представляемых ими:
Эффект от применения "\cx" таков: если "x" это символ в нижнем регистре, он конвертируется в верхний регистр. Затем бит 6 символа (hex 40) инвертируется. Таким образом, "\cz" становится hex 1A, "\c{" становится hex 3B, а "\c;" становиться hex 7B. После "\x" читаются не более двух 16-ричных цифр (буквы могут быть в любом регистре). После "\0" читаются не более четырёх 8-ричных цифр. В обоих случаях, если имеется менее двух цифр, используются именно те, которые представлены. Таким образом, последовательность "\0\x\07" специфицирует два бинарных нуля с последующим символом BEL. Убедитесь, что вы предоставили две цифры после начального нуля, если последующий символ сам является 8-ричным числом. Обработка backslash с последующими цифрами, отличными от 0, сложнее. Вне класса символов, PCRE читает его и любые последующие символы как 10-ричное число. Если число менее 10 или если в выражении имеется по меньшей мере столько же захватывающих левых скобок, вся последовательность считается back reference\обратной ссылкой. Описание того, как этот механизм работает, будет дано позднее в дискуссии о субпатэрнах в скобках. Внутри класса символов, или если 10-ричное число больше 9 и нет такого же количества захватывающих субпатэрнов, PCRE считывает до трёх 8-ричных цифр, идущих после backslash, и генерирует один байт из последних значащих 8 битов этого значения. Любые последующие цифры представляют сами себя. Например:
Заметьте, что 8-ричные значения 100 или более обязаны не вводиться с ведущим 0, поскольку читается не более трёх 8-ричных цифр. Все последовательности, определяющие однобайтное значение, могут использоваться как внутри, так и вне классов символов. Кроме того, внутри класса символов последовательность "\b" интерпретируется как символ backspace (hex 08). Вне класса символов она имеет другое значение (см. далее). Третий вариант использования backslash - специфицирование общего типа символов:
Каждая пара escape-последовательностей разделяет полный набор символов на два различных набора. Любой данный символ совпадает с одной, и только с одной, парой. Символ "word" это любая буква, или цифра, или символ подчёркивания, то есть любой символ, который может быть частью "word" в Perl. Определение букв и цифр контролируется таблицами символов PCRE и может варьироваться, если имеет место подстановка с локальной спецификой (см. ранее "Поддержка локализации"). Например, при локализации "fr" (French) используются некоторые символы с кодами выше 128 для ввода букв с акцентами, и они совпадают с \w. Эти последовательности типов символов могут появляться как внутри, так и вне классов символов. Каждый из них совпадает с одним символом соответствующего типа. Если текущая точка совпадения является концом строки-субъекта, все они терпят неудачу, поскольку отсутствует символ для сравнения. Четвёртый вариант - использование backslash для некоторых простых утверждений. Утверждение специфицирует условие, которое должно быть найдено в определённой точке при подстановке, не используя никаких символов из строки-субъекта. Использование субпатэрнов для более сложных утверждений рассматривается далее. Утверждения с обратными слэшами это:
Эти утверждения не могут появляться в классах символов (но заметьте, что "\b" имеет другое значение, а именно символ backspace, внутри класса символов). Граница слова это такая позиция в строке-субъекте, где текущий и предыдущий символы не совпадают с \w или \W (т.е. один совпадает с \w, а другой - с \W), или начало или конец строки, если первый или последний символ совпадает с \w, соответственно. Утверждения \A, \Z и \z отличаются от традиционных circumflex и dollar (описано далее) тем, что они совпадают только с самым началом и концом строки-субъекта, независимо от установленных опций. На них не влияют опции PCRE_NOTBOL или PCRE_NOTEOL. Разница между \Z и \z в том, что \Z совпадает до newline, то есть является последним символом строки, а также концом строки, в то время как \z совпадает только в конце строки. Circumflex и dollarВне класса символов, в режиме подстановки по умолчанию, символ circumflex (^) является утверждением, которое true, только если текущая точка совпадения является началом строки-субъекта. Внутри класса символов circumflex имеет совершенно иное значение (см. далее). Circumflex не должен быть первым символом патэрна, если используются несколько альтернатив, но должен быть первым в каждой альтернативе, в которой появляется, если патэрн совпадает с данной ветвью. Если все имеющиеся альтернативы начинаются с circumflex (^), то есть если патэрн ограничен для совпадения только в начале субъекта, говорится, что это "заякоренный/anchored" патэрн. (Имеются также и другие конструкции, которые могут вызывать заякоривание патэрна.) Символ dollar является утверждением, которое TRUE, только если текущая точка совпадения находится в конце строки-субъекта или сразу после символа newline, который является последним символом строки (по умолчанию). Dollar не должен быть последним символом патэрна, если дано несколько альтернатив, но должен быть последним символом в любой ветви, в которой он появляется. Dollar не имеет специального значения в классе символов. Значение dollar может быть изменено так, чтобы он совпадал только с самым концом строки, через установку опции PCRE_DOLLAR_ENDONLY во время компиляции или подстановки. Это не влияет на утверждение \Z. Значение символов circumflex и dollar изменяется, если установлена опция PCRE_MULTILINE. В этом случае они совпадают сразу после или сразу до внутреннего символа "\n", соответственно, в дополнение к совпадению в начале и в конце строки-субъекта. Например, патэрн /^abc$/ совпадает со строкой-субъектом "def\nabc" в многострочном режиме, но не иначе. Соответственно, патэрны, которые заякорены в однострочном режиме, если все ветви начинаются с "^", не являются заякоренными в многострочном режиме. Опция PCRE_DOLLAR_ENDONLY игнорируется, если установлена PCRE_MULTILINE. Заметьте, что последовательности \A, \Z и \z могут использоваться для совпадения с началом и концом субъекта в обоих режимах, и если все верви в начале патэрна с \A всегда заякорены, независимо от того, установлена PCRE_MULTILINE или нет. FULL STOP/ПОЛНЫЙ ОСТАНОВВне класса символов точка в патэрне совпадает с одним из символов субъекта, включая непечатаемый символ, но не с символом (по умолчанию) newline. Если установлена опция PCRE_DOTALL, точки совпадают также и с символами newline. Обработка точки зависит всецело от обработки circumflex и dollar, их роднит только то, что они оба вводят символы newline. Точка не имеет специального значения в классе символов. Квадратные скобкиОткрывающая квадратная скобка вводит класс символов, заканчивающийся закрывающей квадратной скобкой. Закрывающая квадратная скобка сама по себе не является специальным символом. если закрывающая квадратная скобка необходима как член класса символов, она должна быть первым символом данных класса (после начального circumflex, если он имеется) или должна заменяться с помощью backslash. Класс символов совпадает с одиночным символом строки-субъекта; символ обязан быть из набора символов, определённого в данном классе, если только первым символом в классе не является circumflex - в этом случае символ строки-субъекта обязан не входить в набор, определённый в данном классе. Если circumflex необходим как член класса, убедитесь, что он не является первым символом, либо escape-ируйте его с помощью обратного слэша (\). Например, класс символов [aeiou] совпадает с любой гласной буквой в нижнем
регистре, а [^aeiou] совпадает с любым символом, не являющимся гласной буквой в нижнем регистре. Если установлено совпадение без учёта регистра, то любая буква класса представляет символы как нижнего, так и верхнего регистров, поэтому, например, безрегистровый [aeiou] совпадает с "A" и с "a", в безрегистровый [^aeiou] совпадает с не-"A" и с не-"a", в то время как регистровая версия совпадает. Символ newline никогда не рассматривается специально в классах символов, вне зависимости от того, установлены опции PCRE_DOTALL или PCRE_MULTILINE или нет. Класс, такой как [^a], всегда будет совпадать с newline. Знак "минус" (дефис) может использоваться для специфицирования диапазона символов в классе символов. Например, [d-m] совпадает с любой буквой от d до m включительно. Если знак минус необходим как член класса, он обязан вводиться заменой с помощью backslash или появляться в позиции, где он не может интерпретироваться как обозначающий диапазон, т.е. обычно как первый или последний символ класса. Невозможно иметь литеральный символ "]" в качестве конца диапазона. Патэрн [W- 46] интерпретируется как класс из двух символов ("W" и "-") с последующей литеральной строкой "46]", поэтому он совпадает с "W46]" или с "-46]". Однако, если "]" escape-ирован с обратным слэшем, он интерпретируется как конец диапазона, поэтому [W-\]46] интерпретируется как единый класс, содержащий диапазон, с последующими двумя отдельными символами. 8-ричное или 16-ричное представление "]" также может использоваться для указания на конец диапазона. Диапазоны оперируют в ASCII-кодировке символов. Они также могут использоваться для символов, специфицированных числами, например [\000-\037]. Если диапазон букв установлен при отключённом распознавании регистра символов, он совпадает с буквами в любом регистре. Например, [W-c] эквивалентно [][\^_`wxyzabc], совпадая без учёта регистра и при использовании таблиц символов для локализации "fr", [\xc8-\xcb] совпадает с акцентированными символами E в любом регистре. Типы символов \d, \D, \s, \S, \w и \W также могут появляться в классах символов и добавлять в класс символы, с которыми они совпадают. Например, [\dABCDEF] совпадает с любым 16-ричным числом. Символ circumflex (^) может быть использован с типами символов верхнего регистра, чтобы специфицировать более ограниченный набор символов - только типы нижнего регистра. Например, класс [^\W_] совпадает с любой буквой или цифрой, но не с символом подчёркивания. Все неалфавитные символы, кроме \, -, ^ (в начале) и заключительного ], являются неспециальными в классах символов, но не повредит вводить их с помощью escape-последовательностей. Vertical bar/Вертикальная чертаСимволы вертикальной черты (|) используются для
разделения альтернативных патэрнов. gilbert|sullivan совпадает с "gilbert" или с "sullivan". Можно вводить любое количество альтернатив, а также пустые альтернативы (совпадающие с пустой строкой). Процесс подстановки испытывает альтернативы по очереди, слева направо, и используется первое найденное совпадение. Если альтернативы находятся в субпатэрне (определен далее), "использование" означает совпадение остатка главного патэрна, а также альтернативы в субпатэрне. Установка внутренних опцийУстановки опций
PCRE_CASELESS,
PCRE_MULTILINE,
PCRE_DOTALL и PCRE_EXTENDED
могут быть изменены из патэрна с помощью последовательности букв-опций Perl,
заключённых между символами "(?" и ")". i для PCRE_CASELESS m для PCRE_MULTILINE s для PCRE_DOTALL x для PCRE_EXTENDED Например, (?im) устанавливает многострочный поиск совпадения без учёта регистра. Можно также отменять установку опции, предваряя букву дефисом, и комбинировать установку и отмену опций, как здесь (?im-sx), где устанавливаются PCRE_CASELESS и PCRE_MULTILINE и отменяются PCRE_DOTALL и PCRE_EXTENDED. Если буква появляется как до, так и после дефиса, опция отменяется. Область видимости этих изменений опций зависит от того, где в патэрне
изменения появляются. Для установок вне субпатэрна (определён далее), эффект
будет таким же, как и при установке и отмене опций в начале совпадения. (?i)abc что, в свою очередь, то же самое, что компиляция патэрна abc с установкой PCRE_CASELESS. Иначе говоря, такие установки "верхнего уровня" применяются ко всему патэрну (если отсутствуют другие изменения в субпатэрнах). Если имеются несколько установок одной опции на верхнем уровне, используется самая правая установка. Если изменение опции возникает внутри субпатэрна, эффект может быть разным. Это
изменение поведения было сделано в Perl 5.005. (a(?i)b)c совпадает с abc и с aBc и больше ни с чем (предполагая, что PCRE_CASELESS не используется). Это означает, что опции могут изменяться для получения различных установок в разных частях патэрна. Любые изменения, сделанные в одной альтернативе, влияют на последующие ветви внутри того же субпатэрна. Например, (a(?i)b|c) совпадает с "ab", "aB", "c" и "C", хотя при совпадении с "C" первая ветвь покидается до установки опции. Это происходит из-за того, что установки опций происходят на этапе компиляции. Иначе поведение будет непредсказуемым. PCRE-специфичные опции PCRE_UNGREEDY и PCRE_EXTRA могут быть изменены так же, как и Perl-совместимые опции, путём использования символов U и X соответственно. Установка флага (?X) является специальной с том плане, что он обязан появляться в патэрне раньше, чем будет включена любая дополнительная возможность, даже если она на верхнем уровне. Лучше всего помещать его при старте. СубпатэрныСубпатэрны ограничены скобками (круглыми), которые могут вкладываться. Маркировка части патэрна как субпатэрна выполняет два действия: 1. Локализует набор альтернатив. Например, патэрн 2. Устанавливает субпатэрн как захватывающий субпатэрн (как определено выше). Когда совпадает весь патэрн целиком, часть строки-субъекта, совпавшая с субпатэрном, передаётся обратно вызывающему посредством аргумента ovector функции pcre_exec(). Открывающие скобки вычисляются слева направо (начиная с 1) для получения количества захватывающих субпатэрнов. Например, если строка "the red king" сопоставляется с патэрном Фактически такое выполнение обычными скобками двух функций не всегда помогает.
Бывают случаи, когда необходим группировка субпатэрнов без необходимости
захвата. Если после открывающей скобки идёт "?:", субпатэрн не выполняет
захвата и не учитывается при подсчёте количества захвативших субпатэрнов. Например,
если строка "the white queen" сопоставляется с патэрном В качестве удобной аббревиатуры, если любые установки опций нужны в начале
незахватывающего субпатэрна, буквы опций могут появляться между "?" и ":".
Таким образом, два субпатэрна ПовторениеПовторение специфицируется квантификаторами, которые могут идти после любого из следующих элементов: одиночного символа, возможно, мнемонизированного Квантификатор общего повторения специфицирует минимальное и
максимальное количество допустимых совпадений, имея два числа в фигурных
скобках, разделённые запятой. Число обязано быть менее 65536, а первое
обязано быть меньше или равно второму. Например: Квантификатор {0} допустим, заставляя выражение вести себя так, будто предыдущий элемент и квантификатор не существуют. Для удобства (и обратной совместимости) три наиболее распространённых
квантификатора имеют односимвольные сокращения: По умолчанию квантификаторы являются "жадными", то есть они совпадают
максимально возможное количество раз (до максимально допустимого количества
раз), не вызывая неудачи выполнения остальной части патэрна. Классический
пример, когда это создаёт проблемы - попытка найти совпадения в комментарии C-программ.
Комментарии появляются между символами /* и */, а внутри могут появляться
отдельные символы * и /. Попытка найти совпадение с C-комментариями, применив патэрн терпит неудачу, поскольку происходит совпадение с целой строкой из-за жадности элемента .*. Однако, если после квантификатора идёт знак вопроса, он перестает быть жадным и
совпадает минимально возможное количество раз, поэтому патэрн Если установлена опция PCRE_UNGREEDY (отсутствующая в Perl), то квантификаторы не жадничают по умолчанию, но отдельные могут быть жадными, если после них стоит знак вопроса. Другими словами, знак вопроса инвертирует поведение по умолчанию. Когда субпатэрн в скобках квантифицирован минимальным количеством повторений, которое больше 1, или имеет ограничение максимума, для откомпилированного патэрна требуется больше места, пропорционально размеру минимума или максимума. Если патэрн начинается с .* или с .{0,} и установлена опция PCRE_DOTALL
(эквивалентная Perl'овской /s), разрешая, таким образом совпадение . с
символами новой строки, то патэрн неявно заякоривается, поскольку всё, что
идёт следом, будет испытываться относительно каждой символьной позиции в
строке-субъекте, поэтому после первой нет другой позиции для возобновления
попыток найти полное совпадение. Когда захватывающий субпатэрн повторяется, захваченным значением является
подстрока, которая совпадает с последней итерацией. Например, после того как Обратные Ссылки/BACK REFERENCESВне класса символов обратный слэш с последующей цифрой больше 0 (и возможными последующими цифрами) является обратной ссылкой на предшествующий захватывающий субпатэрн (т.е. слева от себя) в патэрне, предполагая, что имелось достаточное количество предыдущих захватывающих левых скобок. Однако, если 10-ричное число, идущее после backslash, меньше 10, оно всегда считается обратной ссылкой и вызывает ошибку только тогда, когда во всём патэрне нет достаточного количества захватывающих левых скобок. Другими словами, скобки, на которые ссылаются, не обязаны быть слева от ссылки для числе менее 10. См. в разделе "Обратный слэш/Backslash" ранее детальную информацию об обработке чисел, идущих после обратного слэша. Обратная ссылка совпадает со всем тем, с чем совпадает захватывающий субпатэрн
в текущей строке-субъекте, а не с тем, с чем совпадает сам субпатэрн.
Поэтому патэрн В одном субпатэрне может быть более одной обратной ссылки. Если субпатэрн в
данный момент не используется в определённом совпадении, то любые обратные
ссылки на него терпят неудачу. Например, патэрн Утверждения/AssertionsУтверждение это проверка символов,
идущих следом или предшествующих текущей
точке совпадения, не используя реально никаких символов. Простые утверждения, кодированные как \b,
\B, \A, \Z, \z, ^ и $, были рассмотрены ранее. Более сложные утверждения кодированы как субпатэрны. Субпатэрн утверждения совпадает обычным образом, за исключением того, что он не
вызывает изменения текущей позиции совпадения. Утверждения вперёд начинаются
с (?= для положительного утверждения и с (?! - для отрицательного утверждения. Например, Утверждение назад начинается с (?<= для положительного и с (?<! - для
отрицательного утверждения. Например, Разные утверждения (любого вида) могут следовать друг за другом. Например, Утверждения могут вкладываться в любом сочетании. Например, Субпатэрны утверждений не являются захватывающими субпатэрнами и не могут повторяться, поскольку нет смысла утверждать одно и то же несколько раз (это смотря в какой стране ... - прим. перев.). Если утверждение любого типа содержит захватывающие субпатэрны, они обсчитываются для целей нумерации захватывающих субпатэрнов всего патэрна. Однако захват подстрок выполняется только для положительных утверждений, так как это не имеет смысла для отрицательных утверждений. Утверждения обсчитываю максимум до 200 субпатэрнов. Once-only/"Однократные" субпатэрныИ при минимальном, и при максимальном количестве повторений, неудача того, что идёт следом, нормально вызывает повторное вычисление повторяемого элемента, с целью проверить, не даст ли совпадения повторение, иное количество раз, оставшейся части патэрна. Иногда нужно предотвратить это для изменения природы совпадения, либо чтобы вызвать неудачу раньше, чем это могло бы быть, если автор патэрна знает, что больше нет точек для работы. Рассмотрим, например, патэрн \d+foo в применении к строке-субъекту Альтернативное описание таково, что субпатэрн этого типа совпадает со строкой символов, с которой мог бы совпасть идентичный отдельный субпатэрн, если он заякорен в текущей точке строки-субъекта. Однократные субпатэрны не являются захватывающими субпатэрнами. Простые случаи, вроде вышеприведённого примера, можно представить как максималистское построение, которое поглощает всё, что может. Так, в то время как \d+ и \d+? подготовлены так, чтобы уточнять число цифр для совпадения с ними, чтобы совпала остальная часть патэрна, (?>\d+) может совпадать только с полной последовательностью цифр. Эта конструкция, разумеется, может содержать произвольно усложнённые субпатэрны и может вкладываться. Однократные субпатэрны можно использовать в сочетании с утверждениями назад для
специфицирования эффективного совпадения в конце строки-субъекта. Рассмотрим такой простой патэрн: Если патэрн содержит неограниченное повторение внутри субпатэрна, который сам
может повторяться неограниченное количество раз, использование once-only
субпатэрна оказывается единственным способом избежать неудачных совпадений,
которые длятся достаточно продолжительное время. Условные субпатэрныМожно заставить субпатэрн в процессе совпадения подчиняться условно или
выбирать из двух альтернативных субпатэрнов, в зависимости от результата
утверждения или от того, совпал предшествующий захватывающий субпатэрн или
нет. Вот две возможные формы условного субпатэрна: Есть условия двух видов. Если текст между скобками состоит из
последовательности цифр, то условие выполнено, если захватывающий субпатэрн
этого числа ранее совпал. Рассмотрим следующий патэрн, который содержит
незначащий пробел для удобства чтения (предположим наличие опции
PCRE_EXTENDED) и для разделения патэрна на три части
для облегчения обсуждения: Если условие не является последовательностью цифр, оно обязано быть
утверждением. Это может быть положительное или отрицательное lookahead или lookbehind утверждение. КомментарииПоследовательность символов (?# обозначает начало комментария, который продолжается до следующей закрывающей скобки. Вложение скобок не допускается. Символы, образующие комментарий, не являются частью совпадения патэрна. Если установлена опция PCRE_EXTENDED, не escape-ированный символ # вне класса символов начинает комментарий, который продолжается до следующего символа новой строки в патэрне. Рекурсивные патэрныРассмотрим проблему совпадения строки в скобках,
когда допускается неограниченное вложение скобок. Без использования рекурсии
лучшее, что можно сделать, это использовать патэрн, который совпадает на
некоторую фиксированную глубину вложения. Невозможно обработать вложения на
произвольно большую глубину. В Perl 5.6 имеется экспериментальная
возможность, позволяющая (помимо прочего) выполнять рекурсию регулярных
выражений. Специальный элемент (?R) предоставлен для этого специфического case/варианта рекурсии. Этот особый пример патэрна содержит вложенное бесконечное повторение, и, таким
образом, использование однократного субпатэрна для совпадения со строками из
не-скобок очень важно, когда патэрн применяется к строкам, которые не
совпадают. Например, если его применить к Значения, установленные для любого субпатэрна, берутся с самого внешнего уровня
рекурсии, на котором устанавливается значение субпатэрна. Если вышеприведённый патэрн подставить относительно то строка, захватываемая ими, будет "ab(cd)ef" - содержимое скобок верхнего уровня. ПроизводительностьНекоторые элементы, которые могут появляться в патэрнах, работают более эффективно, чем другие. Более эффективно использовать класс символов, такой как [aeiou], нежели набор альтернатив, такой как (a|e|i|o|u). В целом, более простая конструкция является более эффективной. Книга Jeffrey Friedl'а содержит большую дискуссию об оптимизации регулярных выражений для повышения производительности. Если патэрн начинается с .* и установлена опция PCRE_DOTALL, патэрн неявно заякоривается PCRE, поскольку он может совпасть только в начале
строки-субъекта. Однако, если PCRE_DOTALL не установлена, PCRE не может выполнить эту
оптимизацию, поскольку метасимвол . не совпадает тогда с символом новой строки/newline,
и, если строку-субъект содержит newlines, патэрн может совпасть с
символом, идущим непосредственно после одного из символов новой строки,
вместо того чтобы совпадать только в самом начале. Например, патэрн совпадает в субъекте "first\nand second" (где \n это символ новой строки) с первой захваченной подстрокой "and". Для этого PCRE пытается совпадать в начале после каждого символа новой строки в субъекте. Если вы используете такой патэрн со строками-субъектами, которые не содержат newlines, наилучшая производительность будет достигнута установкой PCRE_DOTALL, или если начать патэрн с ^.* для явного указания заякоривания. Это удержит PCRE от необходимости сканировать субъект в поисках newline для рестарта с него. Избегайте создания патэрнов, которые содержат бесконечные повторения. Они могут занять много времени, если применить их к строке, которая не содержит совпадений. Рассмотрим фрагмент патэрна (a+)*
Он может совпасть с "aaaa" 33 разными способами, и это количество
увеличивается очень быстро по мере увеличения длины строки. (Повторение *
может совпасть 0, 1, 2, 3 или 4 раза, и для каждого случая/case, отличного
от 0, повторения + могут совпадать разное количество раз.) С помощью оптимизации можно отловить наиболее простые случаи, такие как (a+)*bгде следом идёт литеральный символ. Прежде чем полагаться на стандартную процедуру поиска совпадений, PCRE проверяет, имеется ли "b" далее в строке-субъекте, и если нет, совпадение немедленно завершается неудачей. Однако, когда последующего литерала нет, эта оптимизация не может быть использована. Почувствуйте разницу, сравнив поведение (a+)*\dс поведением вышеприведённого патэрна. Первый выдаёт неудачу почти сразу, когда применяется к строке символов "a", а второй затрачивает значительное время на поиск в строках длиной более 20 символов. | ||||||||||
|