Perl Compatible Regular Expressions ( PCRE ) — это библиотека , написанная на языке C , которая реализует механизм регулярных выражений , вдохновленный возможностями языка программирования Perl . Филип Хейзел начал писать PCRE летом 1997 года. [3] Синтаксис PCRE гораздо более мощный и гибкий, чем любой из вариантов регулярных выражений POSIX (BRE, ERE) [4] и чем у многих других библиотек регулярных выражений.
Хотя изначально PCRE был нацелен на эквивалентность функций с Perl, эти две реализации не полностью эквивалентны. В течение фазы PCRE 7.x и Perl 5.9.x два проекта координировали разработку, и функции переносились между ними в обоих направлениях. [5]
В 2015 году был выпущен форк PCRE с пересмотренным программным интерфейсом (API). В исходном программном обеспечении, которое теперь называется PCRE1 (серия 1.xx–8.xx), были исправлены ошибки, но дальнейшего развития не было. По состоянию на 2020 год [обновлять]он считается устаревшим, и текущий выпуск 8.45, вероятно, станет последним. Новый код PCRE2 (серия 10.xx) имеет ряд расширений и улучшений кодирования и является местом, где происходит разработка.
Ряд известных программ с открытым исходным кодом , таких как HTTP-серверы Apache и Nginx , а также языки сценариев PHP и R , включают библиотеку PCRE; проприетарное программное обеспечение может делать то же самое, поскольку библиотека имеет лицензию BSD. Начиная с Perl 5.10, PCRE также доступен в качестве замены для стандартного движка регулярных выражений Perl через re::engine::PCRE
модуль.
Библиотека может быть собрана в Unix, Windows и ряде других сред. PCRE2 распространяется с оболочкой POSIX C, [Примечание 1] несколькими тестовыми программами и служебной программой pcregrep
/, pcre2grep
которая собрана вместе с библиотекой.
Эта дополнительная функция доступна, если она включена при сборке библиотеки PCRE2. Большие преимущества в производительности возможны, когда (например) вызывающая программа использует функцию с совместимыми шаблонами, которые выполняются повторно. Поддержка компилятора just-in-time была написана Золтаном Херцегом и не рассматривается в оболочке POSIX.
Использование системного стека для обратного отслеживания может быть проблематичным в PCRE1, поэтому эта функция реализации была изменена в PCRE2. Теперь для этой цели используется куча, а общий объем может быть ограничен. Проблема переполнения стека , которая регулярно возникала в PCRE1, больше не является проблемой в PCRE2 с версии 10.30 (2017).
Как и в Perl, в PCRE2 есть последовательные правила экранирования: любой не буквенно-цифровой символ может быть экранирован для обозначения его буквального значения путем добавления префикса \
(обратной косой черты) перед символом. Любой буквенно-цифровой символ, которому предшествует обратная косая черта, обычно придает ему особое значение. В случае, когда последовательность не была определена как специальная, возникает ошибка. Это отличается от Perl, который выдает ошибку только в режиме предупреждения (в PCRE2 нет режима предупреждения). В основных регулярных выражениях POSIX иногда обратные косые черты экранировали не буквенно-цифровые символы (например, \.
), а иногда они вводили специальную функцию (например, \(\)
).
Поддерживаются классы однобуквенных символов в дополнение к более длинным именам POSIX. Например, \d
соответствует любой цифре точно так же, как [[:digit:]]
в регулярных выражениях POSIX.
A ?
может быть размещен после любого квантификатора повторения, чтобы указать, что следует использовать самое короткое совпадение. По умолчанию сначала делается попытка самого длинного совпадения и выполняется возврат к более коротким совпадениям: например, a.*?b
будет соответствовать первому "ab" в "ababab", где a.*b
будет соответствовать всей строке.
Если U
флаг установлен, то квантификаторы по умолчанию являются нежадными (ленивыми), а ?
делает их жадными.
Unicode определяет несколько свойств для каждого символа. Шаблоны в PCRE2 могут соответствовать этим свойствам: например, будет соответствовать строке, начинающейся с любого "открывающего знака препинания" и заканчивающейся любым "закрывающим знаком препинания", таким как . Сопоставление определенных "нормальных" метасимволов может управляться свойствами Unicode, когда установлена опция компиляции PCRE2_UCP. Опция может быть установлена для шаблона путем включения в начало шаблона. Опция изменяет поведение следующих метасимволов: , , , , , , , , и некоторых классов символов POSIX. Например, набор символов, соответствующих (символам слов), расширяется для включения букв и букв с ударением, как определено свойствами Unicode. Такое сопоставление медленнее, чем обычная ( только ASCII ) альтернатива без UCP. Обратите внимание, что опция UCP требует, чтобы библиотека была собрана с поддержкой Unicode (это значение по умолчанию для PCRE2). Самые ранние версии PCRE1 поддерживали только код ASCII. Позже была добавлена поддержка UTF-8. Поддержка UTF-16 была добавлена в версии 8.30, а поддержка UTF-32 — в версии 8.32. PCRE2 всегда поддерживал все три кодировки UTF.\p{Ps}.*?\p{Pe}
[abc]
(*UCP)
\B
\b
\D
\d
\S
\s
\W
\w
\w
^
и $
может соответствовать только началу и концу строки или началу и концу каждой «строки» внутри строки, в зависимости от установленных параметров.
При компиляции PCRE выбирается значение по умолчанию для новой строки. То, какой из символов новой строки/переноса строки действует, влияет на то, где PCRE обнаруживает ^
начало и $
конец строки (в многострочном режиме), а также на то, что соответствует точке (независимо от многострочного режима, если не (?s)
установлена опция dotall). Это также влияет на процедуру сопоставления PCRE (начиная с версии 7.0): когда незакрепленный шаблон не соответствует началу последовательности новой строки, PCRE продвигается дальше всей последовательности новой строки, прежде чем повторить попытку сопоставления. Если действующая альтернатива опции новой строки включает CRLF как один из допустимых переносов строки, она не пропускает \n
в CRLF, если шаблон содержит определенные \r
или \n
ссылки (начиная с версии 7.3). Начиная с версии 8.10, метасимвол \N
всегда соответствует любому символу, отличному от символов переноса строки. Он ведет себя так же, как и при отсутствии .
опции dotall aka .(?s)
Параметр newline может быть изменен внешними параметрами при компиляции PCRE и при его запуске. Некоторые приложения, использующие PCRE, предоставляют пользователям средства для применения этого параметра через внешний параметр. Таким образом, параметр newline также может быть указан в начале шаблона с помощью одного из следующих:
(*LF)
Newline — символ перевода строки. Соответствующие переносы строк можно сопоставить с \n
.(*CR)
Новая строка — это возврат каретки. Соответствующие переносы строк можно сопоставить с \r
.(*CRLF)
Newline/linebreak — это возврат каретки, за которым следует перевод строки. Соответствующие переносы строк можно сопоставить с \r\n
.(*ANYCRLF)
Любое из вышеперечисленного, обнаруженное в данных, вызовет обработку новой строки. Соответствующие переносы строк могут быть сопоставлены с или с . Ниже приведены настройки и параметры, касающиеся того, что соответствует обратной косой черте-R.(?:\r\n?|\n)
\R
(*ANY)
Любой из вышеперечисленных плюс специальные переносы строк Unicode.Если режим не UTF-8, соответствующие переносы строк можно сопоставить с [Примечание 2] или .(?:\r\n?|\n|\x0B|\f|\x85)
\R
В режиме UTF-8 два дополнительных символа распознаются как переносы строк (*ANY)
:
В Windows в данных, отличных от Unicode, некоторые ANY
символы переноса строки имеют другие значения.
Например, \x85
может соответствовать горизонтальному многоточию, и если оно встречается во время ANY
действия символа новой строки, оно инициирует обработку символа новой строки.
Ниже приведены настройки и параметры, соответствующие обратной косой черте-R.
При компиляции PCRE выбирается значение по умолчанию для того, что соответствует \R
. Значение по умолчанию может соответствовать либо переносам строк, соответствующим ANYCRLF, либо тем, которые соответствуют ANY. Значение по умолчанию можно переопределить при необходимости, включив (*BSR_UNICODE)
или (*BSR_ANYCRLF)
в начале шаблона. При предоставлении (*BSR..)
параметра вы также можете предоставить параметр, например, . Параметры обратной косой черты-R также могут быть изменены внешними параметрами приложением, вызывающим PCRE2, при компиляции шаблона.(*newline)
(*BSR_UNICODE)(*ANY)rest-of-pattern
Параметры переноса строки, такие как (*LF)
описаны выше; параметры обратной косой черты-R, такие как (*BSR_ANYCRLF)
описаны выше; параметр свойств символов Unicode, (*UCP)
описанный выше; (*UTF8)
параметр, описанный следующим образом: если ваша библиотека PCRE2 скомпилирована с поддержкой UTF , вы можете указать (*UTF)
параметр в начале шаблона вместо установки внешнего параметра для вызова режима UTF-8, UTF-16 или UTF-32.
Шаблон может ссылаться на результаты предыдущего совпадения. Например, (a|b)c\1
будет соответствовать либо "aca", либо "bcb" и не будет соответствовать, например, "acb".
Подшаблон (окруженный скобками, например (...)
) может быть назван путем включения лидирующей скобки ?P<name>
после открывающей скобки. Именованные подшаблоны — это функция, которую PCRE перенял из регулярных выражений Python .
Эта функция впоследствии была принята Perl, поэтому теперь именованные группы также могут быть определены с помощью (?<name>...)
или (?'name'...)
, а также (?P<name>...)
. На именованные группы можно ссылаться обратно, например, с помощью: (?P=name)
(синтаксис Python) или \k'name'
(синтаксис Perl).
В то время как обратная ссылка предоставляет механизм для ссылки на ту часть субъекта, которая ранее соответствовала подшаблону, подпрограмма предоставляет механизм для повторного использования базового ранее определенного подшаблона. Параметры подшаблона, такие как независимость от регистра, фиксируются при определении подшаблона. (a.c)(?1)
будет соответствовать "aacabc" или "abcadc", тогда как использование обратной ссылки (a.c)\1
не будет соответствовать, хотя оба будут соответствовать "aacaac" или "abcabc". PCRE также поддерживает не-Perl конструкцию Oniguruma для подпрограмм. Они указываются с помощью \g<subpat-number>
или \g<subpat-name>
.
Атомная группировка — это способ предотвращения возврата в шаблоне. Например, a++bc
будет соответствовать как можно большему количеству "a" и никогда не будет возвращаться назад, чтобы попробовать на одну меньше.
Шаблоны могут утверждать, что предыдущий текст или последующий текст содержит шаблон, не потребляя сопоставленный текст (утверждение нулевой ширины). Например, / \w+(?=\t)
/ соответствует слову, за которым следует табуляция , не включая саму табуляцию.
Утверждения с ретроспективным просмотром не могут иметь неопределенную длину, хотя (в отличие от Perl) каждая ветвь может иметь различную фиксированную длину.
\K
может использоваться в шаблоне для сброса начала текущего полного совпадения. Это обеспечивает гибкий альтернативный подход к утверждениям о просмотре назад, поскольку отброшенная часть совпадения (часть, которая предшествует \K
) не должна быть фиксированной по длине.
Например, \b
для сопоставления «границ слов» нулевой ширины, аналогично .(?<=\W)(?=\w)|(?<=\w)(?=\W)|^|$
Комментарий начинается (?#
и заканчивается следующей закрывающей скобкой.
Шаблон может ссылаться на себя рекурсивно или на любой подшаблон. Например, шаблон будет соответствовать любой комбинации сбалансированных скобок и "a".\((a*|(?R))*\)
Выражения PCRE могут встраиваться , где n — некоторое число. Это вызовет внешнюю пользовательскую функцию через API PCRE и может использоваться для встраивания произвольного кода в шаблон.(?Cn)
Различия между PCRE2 и Perl (начиная с Perl 5.9.4) включают, помимо прочего: [6]
Это означало, что это будет соответствовать Perl, но не PCRE2 до версии 10.30."<<!>!>!>><>>!>!>!>" =~ /^(<(?:[^<>]+|(?3)|(?1))*>)()(!>!>!>)$/
В Perl результатом будет содержащий «a» и содержащий , но в PCRE результатом будет содержащий «b»."aba" =~ /^(a(b)?)+$/;
$1
$2
undef
$2
Это означает, что \g{}
это однозначно в Perl, но потенциально неоднозначно в PCRE.
Это больше не имеет значения с момента выхода PCRE 8.34 (выпущенной 15 декабря 2013 г.), которая больше не позволяет названиям групп начинаться с цифры. [7]
В утверждениях с ретроспективным просмотром как PCRE, так и Perl требуются шаблоны фиксированной длины.
То есть и PCRE, и Perl запрещают использовать шаблоны переменной длины с использованием квантификаторов в утверждениях с ретроспективным просмотром.
Однако Perl требует, чтобы все альтернативные ветви утверждения просмотра назад имели одинаковую длину, тогда как PCRE допускает, чтобы эти альтернативные ветви имели разную длину, при условии, что каждая ветвь по-прежнему имеет фиксированную длину.
Такие как (??{...})
(обратный вызов, возврат которого оценивается как часть шаблона), или (?{})
конструкция, хотя последнюю можно эмулировать с помощью (?Cn)
.
Глаголы управления рекурсией, добавленные в серии Perl 5.9.x, также не поддерживаются.
Поддержка экспериментальных глаголов управления возвратом (добавленных в Perl 5.10) доступна в PCRE, начиная с версии 7.3.
Это (*FAIL)
, (*F)
, (*PRUNE)
, (*SKIP)
, (*THEN)
, (*COMMIT)
и (*ACCEPT)
.
Соответствующее использование аргументов с глаголами управления возвратом в Perl обычно не поддерживается.
Однако следует отметить, что начиная с версии 8.10 PCRE поддерживает следующие глаголы с указанным аргументом: (*MARK:markName)
, (*SKIP:markName)
, (*PRUNE:markName)
, и (*THEN:markName)
.
Начиная с версии 10.32 PCRE2 поддерживает (*ACCEPT:markName)
, (*FAIL:markName)
, и (*COMMIT:markName)
.
Perl допускает использование квантификаторов в (?!...)
конструкции, что бессмысленно, но безвредно (хотя и неэффективно); PCRE выдает ошибку в версиях до 8.13.
При использовании параметров сборки по умолчанию сопоставление не будет выполнено из-за ограничения, но Perl будет выполнять сопоставление правильно."bbbbXcXaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" =~ /.X(.+)+X/
Perl использует кучу для рекурсии и не имеет жесткого ограничения на глубину рекурсии, тогда как PCRE2 имеет ограничение по умолчанию во время компиляции, которое может быть увеличено или уменьшено вызывающим приложением.
За исключением вышеперечисленных пунктов, PCRE способен проходить тесты в t/op/re_tests
файле Perl " ", одном из основных регрессионных тестов на уровне синтаксиса для механизма регулярных выражений Perl.
\x85
\xC2\x85
(?:\r\n?|\n|\x0B|\f|\xC2\x85)
\xC2\x85
\x{0085}
\u0085
А как насчет PCRE?
- Написано летом 1997 года, размещено на ftp-сайте.
- Люди нашли это и создали список рассылки.
- Было сделано несколько улучшений.