#regex #postgresql
#регулярное выражение #postgresql
Вопрос:
Как распознать шаблон регулярных выражений, включающий подчеркивание в Postgres?
Это мое фактическое регулярное выражение:
[^w]
Символы отлично совпадают, проблема в подчеркивании. Когда я вызываю функцию с этим регулярным выражением, например:
select regexp_replace('hello_world!', '[^w] ', ' ', 'g')
Я ожидаю hello world
. Как также сопоставить подчеркивание?
Комментарии:
1. Результат «привет, мир»? Вы хотели удалить ‘!’, но заменить ‘_’? Или вы ожидаете ‘hello world’ — с висячим пробелом?
Ответ №1:
Проблема в том, что w
символы подчеркивания тоже совпадают, и когда вы используете его в классе отрицаемых символов, шаблон не соответствует _
символам. Вы можете проверить сокращенную escape-таблицу класса:
w
[[:alnum:]_]
(обратите внимание, что подчеркивание включено)
Чтобы удалить все символы, отличные от буквенно-цифровых, вы можете извлечь _
и использовать
select regexp_replace('hello_world!', '[^[:alnum:]] ', ' ', 'g')
Здесь [^[:alnum:]]
соответствует одному или нескольким (
) последовательным символам, отличным от букв и цифр ( [^...]
это отрицаемое выражение в скобках) ( [:alnum:]
класс символов POSIX соответствует буквам и цифрам).
Что ж, вы могли бы также использовать (?:W|_)
. К сожалению, обычная конструкция регулярного выражения, подобная [W_]
, не будет работать, потому что W
(и другие отрицаемые сокращения, такие как S
и D
, являются недопустимыми выражениями внутри скобок. Более подробная информация доступна в руководстве:
Выражения в квадратных скобках,
d
,s
иw
теряют свои внешние скобки, иD
,S
иW
являются незаконными. (Так, например,[a-cd]
эквивалентно[a-c[:digit:]]
. Кроме того,[a-cD]
, что эквивалентно[a-c^[:digit:]]
, является незаконным.)
Чтобы избавиться от результирующих пробелов в конце, вы можете использовать trim
:
select trim(regexp_replace('hello_world!', '[^[:alnum:]] ', ' ', 'g'))
Комментарии:
1.«Выражения в квадратных скобках, ,
d
иs
теряют свои внешние скобки, иw
,D
иS
являются незаконными».W
Руководство: вот почему[W_]
не работает.2. Можно использовать
[^a-zA-Z0-9]
вместо[^[:alnum:]]
в зависимости от предпочтений (длина одинакова).3. Хорошо, я понимаю, почему я неправильно понял эту строку вручную. Я добавлю к ответу.