Строковые операторы
В PostgreSQL существует обширный набор строковых операторов для выполнения различных действий, от простой конкатенации текста и сравнения строк до поиска по регулярным выражениям. Строковые операторы работают с типами char, varchar, а также с собственным типом PostgreSQL text.
Ниже описаны основные операторы сравнения и конкатенации, а также реализация операторов регулярных выражений с учетом и без учета регистра символов.
Базовые операторы сравнения
Базовые операторы сравнения строк и конкатенации, поддерживаемые в PostgreSQL, перечислены в табл. 5.1.
ПРИМЕЧАНИЕ
Ключевые слова LIKE и ILIKE, приводящие к вызову функции 11ke(), иногда называются операторами сравнения строк. Эти ключевые слова рассматриваются ниже в разделе «Функции».
Таблица 5.1. Базовые строковые операторы
Оператор | Синтаксис | Описание |
= | ‘строка!’ = ‘ строка2’ | Возвращает true, если первая строка точно совпадает со второй |
! = | ‘строка!’ != ‘ строка2’ | Возвращает true, если первая строка не совпадает со второй |
о | ‘строка!’ <> ‘ строка2’ | Идентичен оператору != |
< | ‘строка!’ < ‘ строка2’ | Возвращает true, если при лексикографической сортировке первая строка предшествует второй |
<= | ‘строка!’ <= ‘ строка2’ | Возвращает true, если при лексикографической сортировке первая строка предшествует второй или их значения совпадают |
> | ‘строка!’ > ‘ строка2’ | Возвращает true, если при лексикографической сортировке вторая строка предшествует первой |
>= | ‘строка!’ >= ‘ строка2’ | Возвращает true, если при лексикографической сортировке вторая строка предшествует первой или их значения совпадают |
Все операторы сравнения строк возвращают логическое значение (true или false). Лексикографическая сортировка, упоминаемая в табл. 5.1, последовательно сравнивает символы строк и определяет, какой из символов «больше» другого. Если начальные символы двух строк совпадают, проверяются следующие символы (слева направо). Перебор продолжается до тех пор, пока не будут найдены два различающихся символа. В этом алгоритме сортировки «больший» символ выбирается сравнением ASCII-кодов, как показывает следующий пример:
booktown=# SELECT letter, ascii(letter)
booktown-# FROM text_sorting
booktown-# ORDER BY letter ASC;
letter ascii
0 48
1 49
2 50
3 51
A 65
В 66
С 67
D 68
a 97
b 98
с 99
d I 100
(12 rows)
Если вы не уверены в порядке сортировки того или иного символа, воспользуйтесь функцией ascii О для получения его ASCII-кода (функция asci i () описана ниже в разделе «Функции»). В листинге 5.3 из таблицы books выбираются названия всех книг, первая буква которых при сортировке предшествует символу «D».
Листинг 5.3. Сравнение строк
booktown=# SELECT title FROM books
booktown=# WHERE substrCtitle, 1, 1) < ‘D1;
title
2001: A Space Odyssey
Bartholomew and the Oobleck
(2 rows)
Конкатенация
Оператор конкатенации (11) играет очень важную роль при форматировании выходных данных. Как и все операторы, он может использоваться в командах SQL всюду, где могут использоваться константы. Допускается последовательная конкатенация строковых значений, для этого перечисляемые строковые константы или идентификаторы разделяются операторами 11.
Например, оператор конкатенации может использоваться в секции WHERE для фильтрации записей на основании сравнения с символьной строкой. Пример приведен в листинге 5.4.
Листинг 5.4. Конкатенация строк
booktown=# SELECT ‘The Title: ‘ | title || ‘, by ‘ |
booktown-# first_name || ‘ ‘ II lastjiame AS bookjinfo
booktown-# FROM books NATURAL JOIN authors AS a (authorjd) LIMIT 3;
book_info
The Title: The Shining, by Stephen King
The Title: Dune, by Frank Herbert
The Title: 2001: A Space Odyssey, by Arthur C. Clarke
(3 rows)
Операторы регулярных выражений
Если обычного сравнения строк оказывается недостаточно, в PostgreSQL предусмотрены специальные операторы для поиска совпадений по регулярным выражениям. Регулярное выражение похоже на строковую константу, с которой сравнивается исходная строка, но некоторые символы (квадратные скобки, вертикальная черта, обратная косая черта и т. д.) при сравнении интерпретируются особым образом. Если вам доводилось работать с такими программами Unix, как sed, grep или perl, возможно, вы уже знакомы с синтаксисом регулярных выражений.
ПРИМЕЧАНИЕ
Общие сведения о регулярных выражениях приведены в книге Джеффри Фридла (Jeffrey Friedl) «Mastering Regular Expressions».
Регулярное выражение состоит из литералов и метасимволов (специальных символов). Обычно регулярные выражения могут совпадать с несколькими вариантами строковых значений. Пример приведен в листинге 5.5, где в таблице authors ищутся все имена (fi rstjiame), начинающиеся с символа А или Т.
Листинг 5.5. Поиск по регулярному выражению
booktown=# SELECT first_name, last_name
booktown-# FROM authors
booktown-# WHERE firstjiame — «AT1;
fi rstjiame lastjiame
Ariel Denham Tom Christiansen
Arthur C. | Clarke Andrew Brookins
Theodor Seuss j Geisel (5 rows)
Символ ~ в секции WHERE является оператором регулярного выражения, а само регулярное выражение задается строкой ЛА| ЛТ. В него входят специальные символы (метасимволы) л и |, а также литералы А и Т. Метасимволы регулярных выражений описаны ниже в этом пункте.
Важнейшее различие между функцией 11 ke() и операторами регулярных выражений заключается в том, что функция likeO ищет совпадение для всей строки, а операторы регулярных выражений ищут совпадение в произвольной позиции заданной строки, если только в самом регулярном выражении не указано обратное.
Операторы регулярных выражений перечислены в табл. 5.2. Их операндами всегда являются строка с регулярным выражением и текст, в котором ищется совпадение (идентификатор или константа). Все операторы регулярных выражении
возвращают результат логического типа, интерпретация которого зависит от специфики самого оператора.
Таблица 5.2. Операторы регулярных выражений
Оператор | Синтаксис | Описание |
— | ‘ строка’ ~ ‘ выражение’ | Возвращает true, если в строке существует совпадение для регулярного выражения |
i ~ | ‘строка’ \- ‘выражение’ | Возвращает true, если в строке нет совпадения для регулярного выражения |
~* | ‘ строка’ ~* ‘ выражение’ | Возвращает true, если в строке существует совпадение для регулярного выражения (без учета регистра символов) |
|_* | ‘строка’ !-* ‘выражение’ | Возвращает true, если в строке нет совпадения для регулярного выражения (без учета регистра символов) |
В табл. 5.3 перечислены метасимволы регулярных выражений. Как было указано выше, в регулярных выражениях эти символы интерпретируются особым образом.
Таблица 5.3. Метасимволы регулярных выражений
Символ | Синтаксис | Описание |
— | ^выражение | Соответствует началу строки |
$ | выражение$ | Соответствует концу строки |
. | , | Соответствует одному символу |
[ ] | [abc] | Соответствует любому из символов, перечисленных в квадратных скобках |
Г] | ГаЬс] | Соответствует любому символу кроме символов, перечисленных в квадратных скобках |
[-] | [a-z] | Соответствует любому символу из интервала, заданного в квадратных скобках |
Г-] | Га-z] | Соответствует любому символу кроме символов из интервала, заданного в квадратных скобках |
7 | а? | Соответствует нулю экземпляров или одному экземпляру предшествующего символа или подвыражения |
* | а* | Соответствует нулю экземпляров или произвольному количеству экземпляров предшествующего символа или подвыражения |
+ | а+ | Соответствует одному и более экземпляров предшествующего символа или подвыражения |
1 | выражение! \ выражение2 | Соответствует левому или правому подвыражению |
( ) | (выражение!) выражение2 | Группировка подвыражений с явным определением приоритета выполняемых операций |
ПРИМЕЧАНИЕ
Литералы, совпадающие с метасимволами из табл. 5.3, должны экранироваться в строке двумя символами \ (например, знак $ представляется последовательностью \\$).
Регулярные выражения часто применяются для поиска подстрок в строках-литералах большего размера. При поиске соответствия с учетом регистра символов используется оператор -; с оператором -* регистр игнорируется. Примеры приведены в листинге 5.6.
Листинг 5.6. Простой поиск соответствия
booktown=# SELECT title FROM books
booktown-# WHERE title — ‘The’;
title
The Shining The Cat in the Hat The Velveteen Rabbit
The Tell-Tale Heart
(4 rows)
booktown=# SELECT title FROM books
booktown-f WHERE title -* ‘The’; title
The Shining The Cat in the Hat Bartholomew and
the Oobleck Franklin in the Dark The Velveteen Rabbit
The Tell-Tale Heart
(6 rows)
Как видно из результатов, оператор ~* возвращает две дополнительные записи, поскольку выражение соответствует не только подстроке «the», но и любым модификациям в регистре символов этой подстроки (the, tHe, ThE и т. д.).
Если добавить в начало этого регулярного выражения символ л, оно будет соответствовать только подстроке «The», находящейся в начале исходного текста (листинг 5.7).
Конструкция . * обозначает любое количество произвольных символов до следующего подвыражения. В данном примере этим подвыражением является пара строк в круглых скобках (rabbit и heart), разделенных символом |, что соответствует любой из перечисленных строк.
Листинг 5.7. Нетривиальный поиск соответствия
booktown=f SELECT title FROM books
booktown-# WHERE title -* IAThe.*(rabbit|heart)’;
title
The Velveteen Rabbit The Tell-Tale Heart
(2 rows)
Выражение AThe.*(rabbit|heart) означает следующее: соответствие находится лишь в том случае, если строка начинается с символов «The», далее идет любое количество произвольных символов, а после них следует либо подстрока «rabbit», либо подстрока «heart». Оператор ~* (вместо оператора ~) производит сравнение без учета регистра символов.
В листинге 5.8 приведен пример еще более сложного регулярного выражения.
Листинг 5.8. Сложный поиск соответствия
booktown=# SELECT title FROM books
booktown-# WHERE title ~* ‘rt.*[ri]t) | (ingJjune$)’ :
title
The Shining Dune
The Velveteen Rabbit The Tell-Tale Heart
(4 rows)
booktown=#
На первый взгляд регулярное выражение в листинге 5.8 выглядит устрашающе. Но если разбить его на элементы, становится видно, что оно состоит из двух выражений в круглых скобках, разделенных символом [.Таким образом, соответствие будет найдено, если хотя бы одно из этих выражений указывает на значение в поле title.
Продолжая анализ выражения, мы видим, что подвыражение слева от символа | состоит из следующих элементов (слева направо): метасимвол л, за которым следует символ t, затем последовательность .* и пара квадратных скобок с символами г и i, за которыми следует символ t. В переводе на русский язык это означает, что соответствие должно начинаться с буквы t, за которой следует ноль или более символов, пока не будет встречена буква г или 1, после которой немедленно следует буква t. Если хотя бы одно из этих условий не соблюдается, соответствия нет.
Выражение в правой части устроено проще. Оно состоит из двух литералов ing и une, разделенных очередным символом , причем за каждым литералом следует символ $. В переводе это означает, что совпадение должно заканчиваться подстрокой Ing или une. При выполнении любого (благодаря символу |) из этих условий соответствие считается найденным.