9.7. Сопоставление шаблонов#

9.7. Сопоставление шаблонов

9.7. Сопоставление шаблонов

Есть три отдельных подхода к сопоставлению шаблонов, предоставляемых Tantor SE: традиционный оператор LIKE SQL, более новый оператор SIMILAR TO (добавленный в SQL:1999) и регулярные выражения в стиле POSIX. Помимо основных операторов соответствует ли этот шаблон данной строке?, доступны функции для извлечения или замены соответствующих подстрок и разделения строки на соответствующие места.

Подсказка

Если ваши потребности в сопоставлении шаблонов выходят за рамки этого, рассмотрите возможность написания пользовательской функции на Perl или Tcl.

Предостережение

В то время как большинство поисковых запросов с использованием регулярных выражений могут быть выполнены очень быстро, регулярные выражения могут быть созданы таким образом, что требуют произвольного количества времени и памяти для обработки. Будьте осторожны при принятии регулярных выражений из недоверенных источников. Если необходимо это сделать, рекомендуется установить ограничение времени выполнения запроса.

Поиск с использованием шаблонов SIMILAR TO имеет те же угрозы безопасности, так как SIMILAR TO предоставляет множество возможностей, аналогичных регулярным выражениям в стиле POSIX.

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

Операторы сопоставления шаблонов всех трех видов не поддерживают недетерминированные правила сортировки. Если необходимо, примените другое правило сортировки к выражению, чтобы обойти это ограничение.

9.7.1. LIKE

string LIKE pattern [ESCAPE escape-character]
string NOT LIKE pattern [ESCAPE escape-character]

Выражение LIKE возвращает true, если row соответствует заданному pattern. (Как и ожидалось, выражение NOT LIKE возвращает false, если LIKE возвращает true, и наоборот. Эквивалентное выражение: NOT (string LIKE pattern)).

Если pattern не содержит знаков процента или подчеркивания, то шаблон представляет только саму строку; в этом случае LIKE действует как оператор равенства. Подчеркивание (_) в pattern означает (соответствует) любому одному символу; знак процента (%) соответствует любой последовательности из нуля или более символов.

Некоторые примеры:

'abc' LIKE 'abc'    1
'abc' LIKE 'a%'     1
'abc' LIKE '_b_'    1
'abc' LIKE 'c'      0

LIKE сопоставление с шаблоном всегда охватывает всю строку. Поэтому, если требуется сопоставить последовательность где-либо внутри строки, шаблон должен начинаться и заканчиваться знаком процента.

Для сопоставления литерального символа подчеркивания или знака процента без сопоставления других символов, соответствующий символ в pattern должен предшествовать символу экранирования. По умолчанию символ экранирования - обратная косая черта, но можно выбрать другой символ, используя ключевое слово ESCAPE. Чтобы сопоставить сам символ экранирования, напишите два символа экранирования.

Примечание

Если у вас отключена опция standard_conforming_strings, все обратные косые черты, которые вы указываете в литеральных строковых константах, должны быть удвоены. Дополнительную информацию см. в разделе Раздел 4.1.2.1.

Также возможно выбрать отсутствие символа экранирования, написав ESCAPE ''. Это фактически отключает механизм экранирования, что делает невозможным отключение специального значения символов подчеркивания и процента в шаблоне.

Согласно стандарту SQL, если не указано ESCAPE, это означает, что символ экранирования отсутствует (вместо того, чтобы использовать обратную косую черту по умолчанию), и значение ESCAPE нулевой длины запрещено. Поэтому поведение Tantor SE в этом отношении немного отличается от стандарта.

Ключевое слово ILIKE может быть использовано вместо LIKE для выполнения поиска без учета регистра символов в соответствии с активной локалью. Это не является частью стандарта SQL, но является расширением Tantor SE.

Оператор ~~ эквивалентен LIKE, а ~~* соответствует ILIKE. Также существуют операторы !~~ и !~~*, которые представляют собой NOT LIKE и NOT ILIKE соответственно. Все эти операторы являются специфичными для Tantor SE. Вы можете видеть эти имена операторов в выводе EXPLAIN и подобных местах, так как парсер фактически переводит LIKE и другие операторы на эти операторы.

Фразы LIKE, ILIKE, NOT LIKE и NOT ILIKE обычно рассматриваются как операторы в синтаксисе Tantor SE; например, они могут использоваться в конструкциях expression operator ANY (subquery), хотя в них нельзя использовать предложение ESCAPE. В некоторых редких случаях может потребоваться использовать имена базовых операторов вместо них.

Также смотрите оператор starts-with ^@ и соответствующую функцию starts_with(), которые полезны в случаях, когда требуется просто сопоставление начала строки.

9.7.2. Регулярные выражения SIMILAR TO

string SIMILAR TO pattern [ESCAPE escape-character]
string NOT SIMILAR TO pattern [ESCAPE escape-character]

Оператор SIMILAR TO возвращает значение true или false в зависимости от того, соответствует ли его шаблон заданной строке. Он похож на оператор LIKE, за исключением того, что интерпретирует шаблон с использованием определения регулярного выражения стандарта SQL. Регулярные выражения SQL представляют собой любопытное сочетание записи LIKE и общепринятого (POSIX) синтаксиса регулярных выражений.

Как и оператор LIKE, оператор SIMILAR TO успешен только в том случае, если его шаблон соответствует всей строке; это отличается от обычного поведения регулярных выражений, где шаблон может соответствовать любой части строки. Также, как и LIKE, SIMILAR TO использует символы подстановки _ и %, обозначающие любой одиночный символ и любую строку соответственно (это сравнимо с символами . и .* в POSIX регулярных выражениях).

В дополнение к этим возможностям, взятым из функции LIKE, SIMILAR TO поддерживает следующие метасимволы для сопоставления шаблонов, взятые из POSIX регулярных выражений:

  • | обозначает альтернативу (одно из двух возможных вариантов).

  • * обозначает повторение предыдущего элемента ноль или более раз.

  • + обозначает повторение предыдущего элемента один или более раз.

  • ? обозначает повторение предыдущего элемента ноль или один раз.

  • {m} обозначает повторение предыдущего элемента точно m раз.

  • {m,} обозначает повторение предыдущего элемента m или более раз.

  • {m,n} обозначает повторение предыдущего элемента не менее m и не более n раз.

  • Скобки () могут использоваться для группировки элементов в один логический элемент.

  • Выражение в квадратных скобках [...] указывает на класс символов, так же как и в POSIX регулярных выражениях.

Обратите внимание, что точка (.) не является метасимволом для SIMILAR TO.

Как и в случае с оператором LIKE, обратная косая черта отключает специальное значение любого из этих метасимволов. Другой символ экранирования можно указать с помощью ESCAPE, или возможность экранирования можно отключить, написав ESCAPE ''.

Согласно стандарту SQL, если не указано ESCAPE, это означает, что символ экранирования отсутствует (вместо того, чтобы использовать обратную косую черту по умолчанию), и значение ESCAPE нулевой длины запрещено. Поэтому поведение Tantor SE в этом отношении немного отличается от стандарта.

Другим нестандартным расширением является то, что после символа экранирования символом буквы или цифры можно получить доступ к последовательностям экранирования, определенным для регулярных выражений POSIX; см. Таблица 9.20, Таблица 9.21 и Таблица 9.22 ниже.

Некоторые примеры:

'abc' SIMILAR TO 'abc'          1
'abc' SIMILAR TO 'a'            0
'abc' SIMILAR TO '%(b|d)%'      1
'abc' SIMILAR TO '(b|c)%'       0
'-abc-' SIMILAR TO '%\mabc\M%'  1
'xabcy' SIMILAR TO '%\mabc\M%'  0

Функция substring с тремя параметрами позволяет извлекать подстроку, соответствующую шаблону регулярного выражения SQL. Функцию можно написать в соответствии со стандартным синтаксисом SQL:

substring(string similar pattern escape escape-character)

или используя устаревший синтаксис SQL:1999:

substring(string from pattern for escape-character)

или как обычная функция с тремя аргументами:

substring(string, pattern, escape-character)

Как и в случае с SIMILAR TO, указанный шаблон должен полностью соответствовать строке данных, иначе функция завершится с ошибкой и вернет null. Чтобы указать часть шаблона, для которой интересно сопоставление подстроки данных, шаблон должен содержать два вхождения символа экранирования, за которыми следует двойная кавычка ("). Текст, соответствующий части шаблона между этими разделителями, возвращается при успешном совпадении.

Теги escape-double-quote на самом деле разделяют шаблон функции substring на три независимых регулярных выражения; например, вертикальная черта (|)) в любой из трех секций влияет только на эту секцию. Кроме того, первое и третье из этих регулярных выражений определены таким образом, чтобы соответствовать наименьшему возможному количеству текста, а не наибольшему, когда есть неоднозначность в том, какая часть строки данных соответствует какому шаблону. (В терминологии POSIX первое и третье регулярные выражения принудительно делаются нежадными).

В качестве расширения стандарта SQL Tantor SE позволяет использовать только один разделитель для экранирования двойных кавычек, в этом случае третье регулярное выражение считается пустым; или без разделителей, в этом случае первое и третье регулярные выражения считаются пустыми.

Некоторые примеры, с использованием тега #" для разделения возвращаемой строки:

substring('foobar' similar '%#"o_b#"%' escape '#')   oob
substring('foobar' similar '#"o_b#"%' escape '#')    NULL

9.7.3. Регулярные выражения POSIX

Список Таблица 9.16 содержит доступные операторы для сопоставления шаблонов с использованием POSIX регулярных выражений.

Таблица 9.16. Операторы сопоставления с регулярными выражениями

Оператор

Описание

Пример(ы)

text ~ textboolean

Строка соответствует регулярному выражению, с учетом регистра

'thomas' ~ 't.*ma't

text ~* textboolean

Строка соответствует регулярному выражению, без учета регистра

'thomas' ~* 'T.*ma't

text !~ textboolean

Строка не соответствует регулярному выражению, с учетом регистра

'thomas' !~ 't.*max't

text !~* textboolean

Строка не соответствует регулярному выражению, без учета регистра

'thomas' !~* 'T.*ma'f


POSIX регулярные выражения предоставляют более мощное средство для сопоставления шаблонов, чем операторы LIKE и SIMILAR TO. Многие инструменты Unix, такие как egrep, sed или awk, используют язык сопоставления шаблонов, похожий на описанный здесь.

Регулярное выражение - это последовательность символов, которая является сокращенным определением набора строк (регулярное множество). Говорят, что строка соответствует регулярному выражению, если она является членом регулярного множества, описанного регулярным выражением. Как и в случае с LIKE, символы шаблона точно соответствуют символам строки, если они не являются специальными символами в языке регулярных выражений - но регулярные выражения используют другие специальные символы, чем LIKE. В отличие от шаблонов LIKE, регулярное выражение может соответствовать в любом месте в строке, если регулярное выражение явно не привязано к началу или концу строки.

Некоторые примеры:

'abcd' ~ 'bc'     1
'abcd' ~ 'a.c'    true — точка соответствует любому символу
'abcd' ~ 'a.*d'   true — * повторяет предыдущий элемент шаблона
'abcd' ~ '(b|x)'  true — | означает ИЛИ, скобки группируют
'abcd' ~ '^a'     true — ^ якори в начале строки
'abcd' ~ '^(b|c)' false — соответствует, за исключением якорей

Язык шаблонов POSIX подробно описан ниже.

Функция substring с двумя параметрами, substring(string из pattern), позволяет извлекать подстроку, соответствующую шаблону POSIX регулярного выражения. Если совпадений нет, возвращается null, в противном случае возвращается первая часть текста, соответствующая шаблону. Однако, если шаблон содержит скобки, возвращается часть текста, соответствующая первому подвыражению в скобках (того, у которого левая скобка идет первой). Если вы хотите использовать скобки внутри выражения без вызова этого исключения, вы можете поставить скобки вокруг всего выражения. Если вам нужны скобки в шаблоне перед подвыражением, которое вы хотите извлечь, см. описание незахватывающих скобок ниже.

Некоторые примеры:

substring('foobar' from 'o.b')     oob
substring('foobar' from 'o(.)b')   о

Функция regexp_count подсчитывает количество мест, где шаблон POSIX регулярного выражения соответствует строке. Ее синтаксис выглядит следующим образом: regexp_count(string, pattern [, start [, flags ]] ). pattern ищется в string, обычно с начала строки, но если задан параметр start, то с указанного индекса символа. Параметр flags является необязательной текстовой строкой, содержащей одну или несколько одиночных буквенных флагов, которые изменяют поведение функции. Например, включение i в flags указывает на регистронезависимое сравнение. Поддерживаемые флаги описаны в Таблица 9.24.

Некоторые примеры:

regexp_count('ABCABCAXYaxy', 'A.')          3
regexp_count('ABCABCAXYaxy', 'A.', 1, 'i')  4

Функция regexp_instr возвращает начальную или конечную позицию N-го совпадения с шаблоном POSIX регулярного выражения в строке или ноль, если такого совпадения нет. Синтаксис функции выглядит следующим образом: regexp_instr(string, pattern). [, start[, N[, endoption[, flags [, subexpr ]]]]] pattern ищется в string, обычно с начала строки, но если указан параметр start, то с указанного индекса символа. Если указан параметр N, то находится N-ое совпадение с шаблоном, в противном случае находится первое совпадение. Если параметр endoption не указан или указан как ноль, функция возвращает позицию первого символа совпадения. В противном случае endoption должен быть равен единице, и функция возвращает позицию символа, следующего за совпадением. Параметр flags - это необязательная текстовая строка, содержащая одну или несколько однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги описаны в Таблица 9.24. Для шаблона, содержащего подвыражения в скобках, subexpr - это целое число, указывающее, какое подвыражение интересует: результат определяет позицию подстроки, соответствующей этому подвыражению. Подвыражения нумеруются в порядке их ведущих скобок. Когда subexpr не указан или равен нулю, результат определяет позицию всего совпадения, независимо от подвыражений в скобках.

Некоторые примеры:

regexp_instr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                   23
regexp_instr('ABCDEFGHI', '(c..)(...)', 1, 1, 0, 'i', 2)
                                   6

Функция regexp_like проверяет, встречается ли совпадение с шаблоном регулярного выражения POSIX внутри строки, возвращая логическое значение true или false. Синтаксис функции regexp_like(string, pattern [, flags ]). Параметр flags является необязательной текстовой строкой, содержащей один или несколько однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги описаны в Таблица 9.24. Эта функция имеет те же результаты, что и оператор ~, если флаги не указаны. Если указан только флаг i, она имеет те же результаты, что и оператор ~*.

Некоторые примеры:

regexp_like('Hello World', 'world')       0
regexp_like('Hello World', 'world', 'i')  1

Функция regexp_match возвращает текстовый массив совпадающих подстрок в первом совпадении шаблона POSIX регулярного выражения с заданной строкой. Синтаксис функции выглядит следующим образом: regexp_match(string, pattern [, flags ]). Если совпадений не найдено, результатом будет NULL. Если найдено совпадение и pattern не содержит подвыражений в круглых скобках, то результатом будет одноэлементный текстовый массив, содержащий подстроку, соответствующую всему шаблону. Если найдено совпадение и pattern содержит подвыражения в круглых скобках, то результатом будет текстовый массив, где элемент с индексом n соответствует подстроке, совпадающей с n-м подвыражением в pattern (не учитывая незахватывающие скобки; подробности см. ниже). Параметр flags является необязательной текстовой строкой, содержащей одну или несколько однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги описаны в Таблица 9.24.

Некоторые примеры:

SELECT regexp_match('foobarbequebaz', 'bar.*que');
 regexp_match
--------------
 {barbeque}
(1 row)

SELECT regexp_match('foobarbequebaz', '(bar)(beque)');
 regexp_match
--------------
 {bar,beque}
(1 row)

Подсказка

В общем случае, когда вам просто нужна вся совпадающая подстрока или NULL в случае отсутствия совпадения, лучшим решением будет использовать regexp_substr(). Однако regexp_substr() существует только в версии 15 и выше Tantor SE. При работе в более старых версиях вы можете извлечь первый элемент результата regexp_match(), например:

SELECT (regexp_match('foobarbequebaz', 'bar.*que'))[1];
 regexp_match
--------------
 barbeque
(1 row)

Функция regexp_matches возвращает набор текстовых массивов соответствующих подстрок внутри совпадений с шаблоном регулярного выражения POSIX к строке. Синтаксис этой функции такой же, как у regexp_match. Эта функция не возвращает ни одной строки, если нет совпадений, одну строку, если есть совпадение и флаг g не указан, или N строк, если есть N совпадений и флаг g указан. Каждая возвращаемая строка является текстовым массивом, содержащим весь совпадающий подстроку или подстроки, соответствующие заключенным в скобки подвыражениям pattern, как описано выше для regexp_match. regexp_matches принимает все флаги, показанные в Таблица 9.24, а также флаг g, который указывает ему возвращать все совпадения, а не только первое.

Некоторые примеры:

SELECT regexp_matches('foo', 'not there');
 regexp_matches
----------------
(0 rows)

SELECT regexp_matches('foobarbequebazilbarfbonk', '(b[^b]+)(b[^b]+)', 'g');
 regexp_matches
----------------
 {bar,beque}
 {bazil,barf}
(2 rows)

Подсказка

В большинстве случаев следует использовать функцию regexp_matches() с флагом g, так как если вам нужно только первое совпадение, проще и эффективнее использовать функцию regexp_match(). Однако функция regexp_match() существует только в PostgreSQL версии 10 и выше. При работе с более старыми версиями распространенным трюком является использование вызова функции regexp_matches() в подзапросе, например:

SELECT col1, (SELECT regexp_matches(col2, '(bar)(beque)')) FROM tab;

Это создает массив текста, если есть совпадение, или NULL, если его нет, так же, как и regexp_match(). Без подзапроса этот запрос не выведет никакого результата для строк таблицы без совпадения, что обычно не является желаемым поведением.

Функция regexp_replace обеспечивает замену нового текста для подстрок, соответствующих шаблонам POSIX регулярных выражений. Она имеет синтаксис regexp_replace(source, pattern, replacement). [, start [, N ]] [, flags ]). (Обратите внимание, что N не может быть указан если не указано start, но flags может быть указан в любом случае). Строка source возвращается неизменной, если нет совпадения с pattern. Если есть совпадение, строка source возвращается с подстановкой строки replacement вместо совпадающей подстроки. Строка replacement может содержать \n, где n - это 1 до 9, чтобы указать, что подстрока исходной строки, соответствующая n-й подвыражению в скобках шаблона, должна быть вставлена, и она может содержать \&, чтобы указать, что подстрока, соответствующая всему шаблону, должна быть вставлена. Напишите \\, если вам нужно вставить литеральную обратную косую черту в текст замены. pattern ищется в string, обычно с начала строки, но если указан параметр start, то с начала символа с этим индексом. По умолчанию заменяется только первое совпадение шаблона. Если указано N и оно больше нуля, то N-е совпадение шаблона заменяется. Если задан флаг g, или если указано N и оно равно нулю, то все совпадения, начиная с позиции start, заменяются. (Флаг g игнорируется, когда указано N). Параметр flags - это необязательная текстовая строка, содержащая один или несколько однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги (за исключением g) описаны в Таблица 9.24.

Некоторые примеры:

regexp_replace('foobarbaz', 'b..', 'X')
                                   fooXbaz
regexp_replace('foobarbaz', 'b..', 'X', 'g')
                                   fooXX
regexp_replace('foobarbaz', 'b(..)', 'X\1Y', 'g')
                                   fooXarYXazY
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 0, 'i')
                                   X PXstgrXSQL fXnctXXn
regexp_replace('A PostgreSQL function', 'a|e|i|o|u', 'X', 1, 3, 'i')
                                   PostgrXSQL function

Функция regexp_split_to_table разделяет строку, используя регулярное выражение POSIX в качестве разделителя. Она имеет синтаксис regexp_split_to_table(string, pattern [, flags ]). Если нет совпадений с pattern, функция возвращает string. Если есть хотя бы одно совпадение, для каждого совпадения она возвращает текст от конца последнего совпадения (или начала строки) до начала совпадения. Когда больше нет совпадений, она возвращает текст от конца последнего совпадения до конца строки. Параметр flags является необязательной текстовой строкой, содержащей один или несколько однобуквенных флагов, которые изменяют поведение функции. regexp_split_to_table поддерживает флаги, описанные в Таблица 9.24.

Функция regexp_split_to_array ведет себя так же, как и regexp_split_to_table, за исключением того, что regexp_split_to_array возвращает результат в виде массива text. Синтаксис функции следующий: regexp_split_to_array(string, pattern [, flags ]). Параметры такие же, как и для функции regexp_split_to_table.

Некоторые примеры:

SELECT foo FROM regexp_split_to_table('the quick brown fox jumps over the lazy dog', '\s+') AS foo;
  foo
-------
 the
 quick
 brown
 fox
 jumps
 over
 the
 lazy
 dog
(9 rows)

SELECT regexp_split_to_array('the quick brown fox jumps over the lazy dog', '\s+');
              regexp_split_to_array
-----------------------------------------------
 {the,quick,brown,fox,jumps,over,the,lazy,dog}
(1 row)

SELECT foo FROM regexp_split_to_table('the quick brown fox', '\s*') AS foo;
 foo
-----
 t
 h
 e
 q
 u
 i
 c
 k
 b
 r
 o
 w
 n
 f
 o
 x
(16 rows)

Как показывает последний пример, функции разделения по регулярному выражению игнорируют совпадения нулевой длины, которые происходят в начале или конце строки или сразу после предыдущего совпадения. Это противоречит строгому определению сопоставления с регулярным выражением, реализованному другими функциями регулярных выражений, но обычно является наиболее удобным поведением на практике. Другие программные системы, такие как Perl, используют аналогичные определения.

Функция regexp_substr возвращает подстроку, которая соответствует шаблону POSIX регулярного выражения, или NULL, если совпадений нет. Синтаксис функции выглядит следующим образом: regexp_substr(string, pattern). [, start[, N[, flags [, subexpr ]]]] pattern ищется в string, обычно с начала строки, но если указан параметр start, то с указанного индекса символа. Если указан N, то возвращается N-ое совпадение с шаблоном, в противном случае возвращается первое совпадение. Параметр flags - это необязательная текстовая строка, содержащая одну или несколько однобуквенных флагов, которые изменяют поведение функции. Поддерживаемые флаги описаны в Таблица 9.24. Для шаблона, содержащего подвыражения в скобках, subexpr - это целое число, указывающее, какое подвыражение является интересующим: результатом будет подстрока, соответствующая этому подвыражению. Подвыражения нумеруются в порядке их ведущих скобок. Если subexpr не указано или равно нулю, результатом будет весь найденный фрагмент, независимо от подвыражений в скобках.

Некоторые примеры:

regexp_substr('number of your street, town zip, FR', '[^,]+', 1, 2)
                                   town zip
regexp_substr('ABCDEFGHI', '(c..)(...)', 1, 1, 'i', 2)
                                   FGH

9.7.3.1. Подробности регулярных выражений

Регулярные выражения Tantor SE реализованы с использованием программного пакета, написанного Генри Спенсером. Большая часть описания регулярных выражений ниже приведена дословно из его руководства.

Регулярные выражения (RE), определенные в POSIX 1003.2, имеют две формы: расширенные RE или ERE (приблизительно такие, как у egrep), и базовые RE или BRE (приблизительно такие, как у ed). Tantor SE поддерживает обе формы и также реализует некоторые расширения, которые не входят в стандарт POSIX, но стали широко используемыми благодаря их наличию в языках программирования, таких как Perl и Tcl. RE, использующие эти не-POSIX расширения, называются продвинутыми RE или ARE в данной документации. ARE почти точное надмножество ERE, но BRE имеют несколько несовместимостей в обозначениях (а также значительно ограничены). Сначала мы описываем формы ARE и ERE, отмечая функции, которые применяются только к ARE, а затем описываем различия BRE.

Примечание

Tantor SE всегда изначально предполагает, что за регулярным выражением следуют правила ARE. Однако, более ограниченные правила ERE или BRE могут быть выбраны путем добавления встроенной опции к шаблону RE, как описано в Раздел 9.7.3.4. Это может быть полезно для обеспечения совместимости с приложениями, которые ожидают точное соответствие правилам POSIX 1003.2.

Регулярное выражение определяется как одна или несколько ветвей, разделенных |. Оно соответствует любому значению, которое соответствует одной из ветвей.

Ветвь представляет собой ноль или более квантифицированных атомов или ограничений, объединенных вместе. Она соответствует совпадению с первым элементом, за которым следует совпадение со вторым и так далее; пустая ветвь соответствует пустой строке.

Квантифицированный атом - это атом, за которым возможно следует один квантификатор. Без квантификатора он соответствует совпадению с атомом. С квантификатором он может соответствовать некоторому количеству совпадений с атомом. Атом может быть любым из возможностей, показанных в Таблица 9.17. Возможные квантификаторы и их значения показаны в Таблица 9.18.

Ограничение соответствует пустой строке, но соответствует только тогда, когда выполняются определенные условия. Ограничение может использоваться там, где может использоваться атом, за исключением того, что за ним не может следовать квантификатор. Простые ограничения показаны в Таблица 9.19; некоторые дополнительные ограничения описаны позже.

Таблица 9.17. Атомы регулярных выражений

АтомОписание
(re) (где re - это любое регулярное выражение) соответствует совпадению для re, с отмеченным совпадением для возможного отчета
(?:re) как указано выше, но совпадение не отмечается для отчетности (незахватывающий набор круглых скобок) (только для ARE)
. соответствует любому одиночному символу
[chars] выражение в квадратных скобках, соответствующее любому из chars (см. Раздел 9.7.3.2 для более подробной информации)
\k (где k - это неалфавитно-цифровой символ) соответствует этому символу, рассматриваемому как обычный символ, например, \\ соответствует символу обратной косой черты
\c где c является буквенно-цифровым (возможно, с последующими символами) это экранирование, см. Раздел 9.7.3.3 (только в AREs; в EREs и BREs это соответствует c)
{ при следующем символе, отличном от цифры, соответствует символу левой фигурной скобки {; при следующей цифре, это начало bound (см. ниже)
x где x - это одиночный символ без другого значения, соответствует этому символу

Регулярное выражение не может заканчиваться обратной косой чертой (\).

Примечание

Если у вас отключена опция standard_conforming_strings, все обратные косые черты, которые вы указываете в литеральных строковых константах, должны быть удвоены. Дополнительную информацию см. в разделе Раздел 4.1.2.1.

Таблица 9.18. Квантификаторы регулярных выражений

КвантификаторСоответствует
* последовательность 0 или более совпадений атома
+ последовательность из 1 или более совпадений атома
? последовательность из 0 или 1 совпадения атома
{m} последовательность из точно m совпадений атома
{m,} последовательность m или более совпадений атома
{m,n} последовательность от m до n (включительно) совпадений атома; m не может превышать n
*? нежадная версия *
+? нежадная версия +
?? нежадная версия ?
{m}? нежадная версия {m}
{m,}? нежадная версия {m,}
{m,n}? нежадная версия {m,n}

Формы, использующие {...}, известны как границы. Числа m и n внутри границы являются неотрицательными десятичными целыми числами со значениями от 0 до 255 включительно.

Нежадные квантификаторы (доступны только в ARE) соответствуют тем же возможностям, что и их соответствующие обычные (жадные) аналоги, но предпочитают наименьшее количество совпадений вместо наибольшего количества совпадений. См. Раздел 9.7.3.5 для получения более подробной информации.

Примечание

Квантификатор не может непосредственно следовать за другим квантификатором, например, ** недопустимо. Квантификатор не может начинать выражение или подвыражение или следовать за ^ или |.

Таблица 9.19. Ограничения регулярных выражений

ОграничениеОписание
^ соответствует началу строки
$ соответствует концу строки
(?=re) положительный просмотр вперед соответствует в любой точке, где начинается подстрока, соответствующая re (только для ARE)
(?!re) негативный просмотр вперед соответствует в любой точке, где не начинается подстрока, соответствующая re (только для ARE)
(?<=re) положительное обратное совпадение совпадает в любой точке, где подстрока, соответствующая re, заканчивается (только для ARE)
(?<!re) отрицательное обратное обозревание соответствует в любой точке, где не заканчивается подстрока, соответствующая re (только для ARE)

Ограничения «взгляните вперед» и «взгляните назад» не могут содержать обратные ссылки (см. Раздел 9.7.3.3), и все скобки внутри них считаются незахватывающими.

9.7.3.2. Скобочные выражения

A выражение в квадратных скобках - это список символов, заключенных в []. Оно обычно соответствует любому одиночному символу из списка (но см. ниже). Если список начинается с ^, то он соответствует любому одиночному символу не из остального списка. Если два символа в списке разделены -, это сокращение для полного диапазона символов между этими двумя (включительно) в упорядочивающей последовательности, например, [0-9] в ASCII соответствует любой десятичной цифре. Запрещено, чтобы два диапазона имели общую границу, например, a-c-e. Диапазоны очень зависят от упорядочивающей последовательности, поэтому переносимые программы должны избегать полагаться на них.

Чтобы включить литерал ] в список, сделайте его первым символом (после ^, если он используется). Чтобы включить литерал -, сделайте его первым или последним символом, или вторым конечным значением диапазона. Чтобы использовать литерал - в качестве первого значения диапазона, заключите его в [. и .], чтобы сделать его сортирующим элементом (см. ниже). За исключением этих символов, некоторых комбинаций с использованием [ (см. следующие абзацы) и экранирования (только для ARE), все остальные специальные символы теряют свое особое значение в пределах выражения в квадратных скобках. В частности, \ не является специальным символом при следовании правилам ERE или BRE, хотя он является специальным (как введение экранирования) в ARE.

В пределах выражения в квадратных скобках, сортирующий элемент (символ, последовательность символов, которая сортируется как один символ или имя последовательности сортировки) заключенный в [. и .] представляет собой последовательность символов этого сортирующего элемента. Последовательность рассматривается как один элемент списка выражения в квадратных скобках. Это позволяет выражению в квадратных скобках, содержащему многосимвольный сортирующий элемент, соответствовать более чем одному символу, например, если последовательность сортировки включает сортирующий элемент ch, то РВ [[.ch.]]*c соответствует первым пяти символам chchcc.

Примечание

Tantor SE в настоящее время не поддерживает многобайтовые сортирующие элементы. Эта информация описывает возможное будущее поведение.

Внутри выражения в квадратных скобках, элемент сортировки, заключенный в [= и =], представляет собой класс эквивалентности, означающий последовательности символов всех элементов сортировки, эквивалентных данному, включая его самого. (Если нет других эквивалентных элементов сортировки, то обработка происходит так, как если бы внешние разделители были [. и .]). Например, если o и ^ являются членами класса эквивалентности, то [[=o=]], [[=^=]] и [o^] являются синонимами. Класс эквивалентности не может быть конечной точкой диапазона.

В пределах выражения в квадратных скобках имя класса символов, заключенное между [: и :], означает список всех символов, принадлежащих этому классу. Класс символов не может использоваться в качестве конечной точки диапазона. Стандарт POSIX определяет следующие имена классов символов: alnum (буквы и цифры), alpha (буквы), blank (пробел и табуляция), cntrl (управляющие символы), digit (цифры), graph (печатные символы, кроме пробела), lower (строчные буквы), print (печатные символы, включая пробел), punct (знаки препинания), space (любой пробельный символ), upper (заглавные буквы), и xdigit (шестнадцатеричные цифры). Поведение этих стандартных классов символов обычно согласовано на разных платформах для символов из 7-битного набора ASCII. Определение того, принадлежит ли данный символ не-ASCII одному из этих классов, зависит от правила сортировки, используемого для функции или оператора регулярного выражения (см. Раздел 23.2), или по умолчанию от настройки локали LC_CTYPE базы данных (см. Раздел 23.1). Классификация не-ASCII символов может отличаться на разных платформах, даже в похожих локалях. (Однако локаль C никогда не считает, что не-ASCII символы принадлежат одному из этих классов). В дополнение к этим стандартным классам символов, Tantor SE определяет класс символов word, который включает в себя символы из класса alnum и символ подчеркивания (_), а также класс символов ascii, который содержит ровно 7-битный набор ASCII.

Есть два особых случая скобочных выражений: выражения вида [[:<:]] и [[:>:]] являются ограничениями, соответствующими пустым строкам в начале и конце слова соответственно. Слово определяется как последовательность символов слова, которая не предшествует и не следует за символами слова. Символ слова - это любой символ, принадлежащий классу символов word, то есть любая буква, цифра или подчеркивание. Это расширение, совместимое, но не указанное в POSIX 1003.2, и следует использовать с осторожностью в программном обеспечении, предназначенном для переносимости на другие системы. Описанные ниже ограничения экранирования обычно предпочтительнее; они не являются стандартными, но их легче набирать.

9.7.3.3. Экранирование регулярных выражений

Экранирования - это специальные последовательности, начинающиеся с \, за которыми следует буквенно-цифровой символ. Экранирования имеют несколько разновидностей: символьные записи, сокращения классов, экранирования ограничений и обратные ссылки. \, за которым следует буквенно-цифровой символ, но не являющийся допустимым экранированием, является недопустимым в ARE. В ERE нет экранирований: вне выражения в квадратных скобках, \, за которым следует буквенно-цифровой символ, просто означает этот символ как обычный символ, а внутри выражения в квадратных скобках \ является обычным символом. (Последнее является единственным фактическим несовместимостью между ERE и ARE).

Существуют символьные экранирования, чтобы упростить указание непечатных и других неудобных символов в регулярных выражениях. Они показаны в Таблица 9.20.

Class-shorthand escapes предоставляют сокращения для определенных часто используемых классов символов. Они показаны в Таблица 9.21.

Ограничение escape - это ограничение, соответствующее пустой строке при выполнении определенных условий, записанных в виде escape. Они показаны в Таблица 9.22.

Обратная ссылка back reference (\n) соответствует той же строке, которая соответствует предыдущему подвыражению, указанному номером n (см. Таблица 9.23). Например, ([bc])\1 соответствует bb или cc, но не bc или cb. Подвыражение должно полностью предшествовать обратной ссылке в RE. Подвыражения нумеруются в порядке их ведущих скобок. Незахватывающие скобки не определяют подвыражения. Обратная ссылка учитывает только символы строки, соответствующие ссылочному подвыражению, а не какие-либо ограничения, содержащиеся в нем. Например, (^\d)\1 будет соответствовать 22.

Таблица 9.20. Экранирование символов в регулярных выражениях

ЭкранированиеОписание
\a символ оповещения (звонок), как в C
\b символ возврата на одну позицию, как в языке C
\B синоним для обратной косой черты (\), чтобы уменьшить необходимость удвоения обратной косой черты
\cX (где X - любой символ) символ, у которого младшие 5 бит совпадают с битами X, а остальные биты равны нулю
\e символ, имя сортировочной последовательности которого является ESC, или, в случае неудачи, символ с восьмеричным значением 033
\f перевод страницы, как в C
\n новая строка, как в C
\r возврат каретки, как в C
\t горизонтальная табуляция, как в C
\uwxyz (где wxyz - это ровно четыре шестнадцатеричных цифры) символ, чье шестнадцатеричное значение равно 0xwxyz
\Ustuvwxyz (где stuvwxyz - это ровно восемь шестнадцатеричных цифр) символ, шестнадцатеричное значение которого 0xstuvwxyz
\v вертикальная табуляция, как в C
\xhhh (где hhh - любая последовательность шестнадцатеричных цифр) символ, чье шестнадцатеричное значение равно 0xhhh (один символ, независимо от количества использованных шестнадцатеричных цифр)
\0 символ, значение которого равно 0 (нулевой байт)
\xy (где xy - это ровно две восьмеричные цифры, и не является обратной ссылкой) символ, чье восьмеричное значение равно 0xy
\xyz (где xyz - это ровно три восьмеричных цифры, и не является обратной ссылкой) символ, чье восьмеричное значение равно 0xyz

Шестнадцатеричные цифры представлены символами 0-9, a-f и A-F. Восьмеричные цифры представлены символами 0-7.

Числовые символьные эскейпы, указывающие значения за пределами диапазона ASCII (0–127), имеют значения, зависящие от кодировки базы данных. При использовании кодировки UTF-8, значения эскейпа эквивалентны кодовым точкам Unicode, например \u1234 означает символ U+1234. Для других многобайтовых кодировок символьные эскейпы обычно просто указывают конкатенацию значений байтов для символа. Если значение эскейпа не соответствует ни одному допустимому символу в кодировке базы данных, ошибки не будет возбуждено, но оно никогда не будет соответствовать данным.

Символьные экранирования всегда воспринимаются как обычные символы. Например, \135 в ASCII представляет собой символ ], но \135 не является завершающим символом для выражения в квадратных скобках.

Таблица 9.21. Сокращенные экранирования классов регулярных выражений

ЭкранированиеОписание
\d соответствует любой цифре, как [[:digit:]]
\s соответствует любому символу пробела, как [[:space:]]
\w соответствует любому символу слова, как [[:word:]]
\D соответствует любому символу, не являющемуся цифрой, как [^[:digit:]]
\S соответствует любому символу, не являющемуся пробелом, как [^[:space:]]
\W соответствует любому символу, не являющемуся буквой или цифрой, как [^[:word:]]

Класс-сокращения также работают внутри скобочных выражений, хотя определения, показанные выше, не являются полностью синтаксически корректными в этом контексте. Например, [a-c\d] эквивалентно [a-c[:digit:]].

Таблица 9.22. Экранирование регулярных выражений в ограничениях

ЭкранированиеОписание
\A соответствует только началу строки (см. Раздел 9.7.3.5 для различий с ^)
\m соответствует только в начале слова
\M соответствует только в конце слова
\y соответствует только началу или концу слова
\Y соответствует только в точке, которая не является началом или концом слова
\Z соответствует только в конце строки (см. Раздел 9.7.3.5 для различий с $)

Слово определяется как в спецификации [[:<:]] и [[:>:]] выше. Экранирование ограничений недопустимо внутри скобочных выражений.

Таблица 9.23. Обратные ссылки в регулярных выражениях

ЭкранированиеОписание
\m (где m - ненулевая цифра) обратная ссылка на m-е подвыражение
\mnn (где m - ненулевая цифра, а nn - еще несколько цифр, и десятичное значение mnn не превышает количество закрывающих захватывающих скобок, увиденных до этого) обратная ссылка на mnn-е подвыражение

Примечание

Существует врожденная неоднозначность между восьмеричными символьными эскейп-последовательностями и обратными ссылками, которая разрешается следующими эвристическими алгоритмами, как указано выше. Ведущий ноль всегда указывает на восьмеричный эскейп. Одна ненулевая цифра, не за которой следует другая цифра, всегда принимается как обратная ссылка. Многозначная последовательность, не начинающаяся с нуля, принимается как обратная ссылка, если она следует после подходящего подвыражения (т.е. число находится в допустимом диапазоне для обратной ссылки), и в противном случае принимается как восьмеричная.

9.7.3.4. Метасинтаксис регулярных выражений

В дополнение к основному синтаксису, описанному выше, существуют некоторые специальные формы и различные синтаксические возможности.

РЕ может начинаться с одного из двух специальных префиксов director. Если РЕ начинается с ***:, остаток РЕ считается ARE. (Это обычно не имеет эффекта в Tantor SE, так как РЕ предполагаются ARE; но это имеет эффект, если ERE или BRE режим был указан в параметре flags функции регулярного выражения). Если РЕ начинается с ***=, остаток РЕ считается литеральной строкой, где все символы считаются обычными символами.

ARE может начинаться с встроенных опций: последовательность (?xyz) (где xyz - одна или несколько буквенных символов) определяет опции, влияющие на остаток регулярного выражения. Эти опции переопределяют любые ранее определенные опции — в частности, они могут переопределить поведение, связанное с регистрозависимостью, заданное оператором регулярного выражения или параметром flags функции регулярного выражения. Доступные буквы опций показаны в Таблица 9.24. Обратите внимание, что эти же буквы опций используются в параметрах flags функций регулярного выражения.

Таблица 9.24. ARE Встроенные опционные буквы

ОпцияОписание
b остаток RE является BRE
c чувствительное к регистру сопоставление (переопределяет тип оператора)
e остаток RE является ERE
i регистронезависимое сопоставление (см. Раздел 9.7.3.5) (переопределяет тип оператора)
m исторический синоним для n
n чувствительное к переводу строки сопоставление (см. Раздел 9.7.3.5)
p частичное сопоставление с учетом переноса строки (см. Раздел 9.7.3.5)
q остаток RE - это буквальная (цитируемая) строка, все обычные символы
s сопоставление, нечувствительное к символу перехода строки (по умолчанию)
t сжатый синтаксис (по умолчанию; см. ниже)
w обратное частичное сопоставление с учетом переноса строки (странный) (см. Раздел 9.7.3.5)
x расширенный синтаксис (см. ниже)

Встроенные опции вступают в силу после символа ), завершающего последовательность. Они могут появляться только в начале ARE (после директивы ***:, если таковая имеется).

В дополнение к обычному синтаксису RE (tight), в котором все символы имеют значение, существует расширенный синтаксис, доступный при указании встроенной опции x. В расширенном синтаксисе пробельные символы в RE игнорируются, а также все символы между символом # и следующим символом перехода строки (или концом RE). Это позволяет разбивать на абзацы и комментировать сложные RE. Есть три исключения из этого основного правила:

  • символ пробела или #, предшествующий символу \, сохраняется

  • белый пробел или # внутри выражения в квадратных скобках сохраняется

  • белый пробел и комментарии не могут появляться внутри многозначных символов, таких как (?:

Для этой цели, символы пробела включают пробел, табуляцию, перевод строки и любой символ, принадлежащий классу символов space.

Наконец, в ARE, вне скобочных выражений, последовательность (?#ttt) (где ttt - любой текст, не содержащий )) является комментарием, полностью игнорируемым. Опять же, это не разрешено между символами многозначных символов, таких как (?:. Такие комментарии являются скорее историческим артефактом, чем полезным средством, и их использование устарело; вместо этого используйте расширенный синтаксис.

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

9.7.3.5. Правила сопоставления регулярных выражений

В случае, если регулярное выражение может соответствовать более чем одной подстроке данной строки, оно соответствует той, которая начинается раньше в строке. Если регулярное выражение может соответствовать более чем одной подстроке, начинающейся с этой точки, будет выбрано либо самое длинное возможное совпадение, либо самое короткое возможное совпадение, в зависимости от того, является ли регулярное выражение жадным или нежадным.

Независимо от того, является ли RE жадным или нет, это определяется следующими правилами:

  • Большинство атомов и все ограничения не имеют атрибута жадности (потому что они все равно не могут соответствовать переменному количеству текста).

  • Добавление скобок вокруг регулярного выражения не изменяет его жадность.

  • Атом с квантификатором фиксированного повторения ({m} или {m}?) имеет такую же жадность (возможно, никакую) как сам атом.

  • Квантифицированный атом с другими обычными квантификаторами (включая {m,n} с m, равным n) является жадным (предпочитает самое длинное совпадение).

  • Атом с квантификатором нежадного типа (включая {m,n}? с m, равным n) является нежадным (предпочитает самое короткое совпадение).

  • Ветвь — то есть, регулярное выражение, которое не имеет оператора | на верхнем уровне — имеет такую же жадность, как и первый квантифицированный атом в нем, который имеет атрибут жадности.

  • Регулярное выражение, состоящее из двух или более ветвей, соединенных оператором |, всегда является жадным.

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

Пример того, что это означает:

SELECT SUBSTRING('XY1234Z', 'Y*([0-9]{1,3})');
Результат:123
SELECT SUBSTRING('XY1234Z', 'Y*?([0-9]{1,3})');
Результат:1

В первом случае RE в целом является жадным, потому что Y* является жадным. Он может совпадать, начиная с Y, и совпадает с самой длинной возможной строкой, начинающейся с него, т.е. Y123. Выводится заключенная в скобки часть этой строки, т.е. 123. Во втором случае RE в целом является нежадным, потому что Y*? является нежадным. Он может совпадать, начиная с Y, и совпадает с самой короткой возможной строкой, начинающейся с него, т.е. Y1. Подвыражение [0-9]{1,3} является жадным, но оно не может изменить решение относительно длины общего совпадения; поэтому оно вынуждено совпадать только с 1.

Вкратце, когда регулярное выражение содержит как жадные, так и нежадные подвыражения, общая длина совпадения может быть как можно длиннее или как можно короче, в зависимости от атрибута, присвоенного всему регулярному выражению. Атрибуты, присвоенные подвыражениям, влияют только на то, сколько из этого совпадения они могут "съесть" относительно друг друга.

Квантификаторы {1,1} и {1,1}? могут быть использованы для принудительного жадного или нежадного поведения, соответственно, в подвыражении или во всем регулярном выражении. Это полезно, когда вам нужно, чтобы всему регулярному выражению был присвоен атрибут жадности, отличный от того, что выведен из его элементов. В качестве примера, предположим, что мы пытаемся разделить строку, содержащую некоторые цифры, на цифры и части до и после них. Мы можем попытаться сделать это так:

SELECT regexp_match('abc01234xyz', '(.*)(\d+)(.*)');
Результат:{abc0123,4,xyz}

Это не сработало: первый .* слишком жадный, поэтому он "съедает" все, что может, оставляя \d+ для совпадения в последнем возможном месте, последней цифре. Мы можем попытаться исправить это, сделав его нежадным:

SELECT regexp_match('abc01234xyz', '(.*?)(\d+)(.*)');
Результат:{abc,0,""}

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

SELECT regexp_match('abc01234xyz', '(?:(.*?)(\d+)(.*)){1,1}');
Результат:{abc,01234,xyz}

Управление общей жадностью РВ отдельно от жадности его компонентов позволяет обеспечить большую гибкость в обработке шаблонов переменной длины.

При принятии решения о том, что является более длинным или коротким совпадением, длина совпадений измеряется в символах, а не в сортирующих элементах. Пустая строка считается длиннее, чем отсутствие совпадения вообще. Например: bb* совпадает с тремя средними символами abbbc; (week|wee)(night|knights) совпадает со всеми десятью символами weeknights; когда (.*).* совпадает с abc, подвыражение в скобках совпадает со всеми тремя символами; и когда (a*)* совпадает с bc, как вся регулярное выражение, так и подвыражение в скобках совпадают с пустой строкой.

Если указано сопоставление без учета регистра, то это имеет тот же эффект, что и если бы все различия регистра исчезли из алфавита. Когда буква, которая существует в нескольких регистрах, появляется как обычный символ вне выражения в квадратных скобках, она фактически преобразуется в выражение в квадратных скобках, содержащее оба регистра, например, x становится [xX]. Когда она появляется внутри выражения в квадратных скобках, все регистровые варианты этой буквы добавляются в выражение в квадратных скобках, например, [x] становится [xX], а [^x] становится [^xX].

Если указано сопоставление, чувствительное к переводу строки, . и выражения в квадратных скобках с использованием ^ никогда не будут соответствовать символу перехода строки (таким образом, совпадения не будут пересекать строки, если РВ явно не содержит символ перехода строки), а ^ и $ будут соответствовать пустой строке после и перед символом перехода строки соответственно, в дополнение к соответствию в начале и конце строки соответственно. Однако экранированные символы ARE \A и \Z продолжают соответствовать только началу или концу строки. Кроме того, сокращения символьных классов \D и \W будут соответствовать символу перехода строки независимо от этого режима. (До Tantor SE 14 они не соответствовали символам перехода строки в режиме, чувствительном к переводу строки. Для получения старого поведения используйте запись [^[:digit:]] или [^[:word:]]).

Если указано частичное сопоставление с учетом символов перехода строки, это влияет на символ . и выражения в квадратных скобках так же, как и при сопоставлении с учетом символов перехода строки, но не на символы ^ и $.

Если указано обратное частичное сопоставление с учетом перехода строки, это влияет на символы ^ и $ так же, как и при сопоставлении с учетом перехода строки, но не на символы . и выражения в квадратных скобках. Это не очень полезно, но предоставляется для симметрии.

9.7.3.6. Ограничения и совместимость

В этой реализации не накладывается особого ограничения на длину регулярных выражений. Однако, программы, предназначенные для высокой переносимости, не должны использовать регулярные выражения длиннее 256 байт, так как совместимая с POSIX реализация может отказаться принимать такие регулярные выражения.

Единственная особенность ARE, которая фактически несовместима с POSIX ERE, заключается в том, что символ \ не теряет своего специального значения внутри выражений в квадратных скобках. Все остальные функции ARE используют синтаксис, который является недопустимым или имеет неопределенные или неуказанные эффекты в POSIX ERE; синтаксис директив *** также находится вне синтаксиса POSIX как для BRE, так и для ERE.

Многие расширения ARE заимствованы из Perl, но некоторые из них были изменены для их улучшения, и некоторые Perl-расширения отсутствуют. Известными несовместимостями являются \b, \B, отсутствие особого обращения к завершающему символу перехода строки, добавление дополнительных выражений в квадратных скобках к вещам, которые подвержены сопоставлению с учетом символа перехода строки, ограничения на скобки и обратные ссылки в ограничениях просмотра вперед/назад и семантика сопоставления наиболее длинного/кратчайшего совпадения (вместо первого совпадения).

9.7.3.7. Основные регулярные выражения

BREs отличаются от EREs в нескольких отношениях. В BREs, |, + и ? являются обычными символами, и нет эквивалента для их функциональности. Разделителями для границ являются \{ и \}, сами символы { и } являются обычными символами. Скобки для вложенных подвыражений - это \( и \), сами символы ( и ) являются обычными символами. ^ является обычным символом, за исключением начала RE или начала подвыражения в скобках, $ является обычным символом, за исключением конца RE или конца подвыражения в скобках, и * является обычным символом, если он появляется в начале RE или начале подвыражения в скобках (после возможного ведущего ^). Наконец, доступны однозначные обратные ссылки, и \< и \> являются синонимами для [[:<:]] и [[:>:]] соответственно; в BREs нет других экранирований.

9.7.3.8. Различия с SQL-стандартом и XQuery

С SQL:2008 стандарт SQL включает операторы и функции регулярных выражений, которые выполняют сопоставление с шаблоном в соответствии со стандартом регулярных выражений XQuery:

  • LIKE_REGEX

  • OCCURRENCES_REGEX

  • POSITION_REGEX

  • SUBSTRING_REGEX

  • TRANSLATE_REGEX

Tantor SE в настоящее время не реализует эти операторы и функции. В каждом случае вы можете получить приблизительно эквивалентную функциональность, как показано в Таблица 9.25. (В этой таблице не указаны различные необязательные предложения с обеих сторон).

Таблица 9.25. Эквиваленты функций регулярных выражений

Стандарт SQLPostgreSQL
string LIKE_REGEX patternregexp_like(string, pattern) или string ~ pattern
OCCURRENCES_REGEX(pattern IN string)regexp_count(string, pattern)
POSITION_REGEX(pattern В string)regexp_instr(string, pattern)
SUBSTRING_REGEX(pattern IN string)regexp_substr(string, pattern)
TRANSLATE_REGEX(pattern В string С replacement)regexp_replace(string, pattern, replacement)

Функции регулярных выражений, аналогичные тем, которые предоставляет PostgreSQL, также доступны во многих других реализациях SQL, в то время как стандартные функции SQL не так широко реализованы. Некоторые детали синтаксиса регулярных выражений, вероятно, будут отличаться в каждой реализации.

Стандартные операторы и функции SQL используют регулярные выражения XQuery, которые довольно близки к синтаксису ARE, описанному выше. Заметные различия между существующей функцией регулярных выражений на основе POSIX и регулярными выражениями XQuery включают:

  • Вычитание символов XQuery не поддерживается. Примером использования этой функции является следующее: чтобы сопоставить только английские согласные, используйте [a-z-[aeiou]].

  • Сокращения классов символов XQuery \c, \C, \i и \I не поддерживаются.

  • Элементы класса символов XQuery, использующие \p{UnicodeProperty} или обратное \P{UnicodeProperty}, не поддерживаются.

  • POSIX интерпретирует классы символов, такие как \w (см. Таблица 9.21) в соответствии с текущей локалью (которую можно контролировать, присоединив к оператору или функции предложение COLLATE). XQuery определяет эти классы с помощью ссылки на свойства символов Unicode, поэтому эквивалентное поведение достигается только с локалью, следующей правилам Unicode.

  • Стандарт SQL (а не сам XQuery) пытается учитывать больше вариантов символа перехода строки, чем POSIX. Описанные выше опции с учетом символа перехода строки рассматривают только ASCII NL (\n) как символ перехода строки, но SQL также требует, чтобы мы рассматривали CR (\r), CRLF (\r\n) (символ перехода строки в стиле Windows) и некоторые символы, доступные только в Юникоде, такие как LINE SEPARATOR (U+2028), как символы перехода строки. Особенно важно отметить, что символы . и \s в соответствии с SQL должны считаться одним символом, а не двумя, если речь идет о символе перехода строки \r\n.

  • Из символьных эскейп-последовательностей, описанных в Таблица 9.20, XQuery поддерживает только \n, \r, и \t.

  • XQuery не поддерживает синтаксис [:name:] для символьных классов внутри квадратных скобок.

  • XQuery не имеет ограничений на просмотр вперед или назад, ни любых из управляющих последовательностей, описанных в Таблица 9.22.

  • В XQuery отсутствуют метасинтаксические формы, описанные в Раздел 9.7.3.4.

  • Буквы флагов регулярных выражений, определенные в XQuery, связаны, но не совпадают с буквами опций для POSIX (Таблица 9.24). В то время как опции i и q ведут себя одинаково, другие - нет:

    • XQuery's s (позволяет точке соответствовать символу перехода строки) и m (позволяет символам ^ и $ соответствовать началу и концу строки) флаги предоставляют доступ к тем же функциям, что и флаги n, p и w в POSIX, но они не соответствуют поведению флагов s и m в POSIX. Обратите внимание, что по умолчанию в POSIX символ перехода строки соответствует точке, но не в XQuery.

    • Флаг x в XQuery (игнорирование пробелов в шаблоне) заметно отличается от флага expanded-mode в POSIX. Флаг x в POSIX также позволяет использовать символ # для начала комментария в шаблоне, и POSIX не будет игнорировать пробел после обратной косой черты.