Проблема в том, что \w
также соответствует подчеркиванию, и когда вы используете его в классе символов с отрицанием, шаблон не соответствует символам _
. Вы можете проверить управляющую таблицу для стенографии :
\w
[[:alnum:]_]
(примечание подчеркивание включено)
Чтобы удалить все символы, кроме буквенно-цифровых, вы можете извлечь _
и использовать
select regexp_replace('hello_world!', '[^[:alnum:]]+', ' ', 'g')
Здесь [^[:alnum:]]+
соответствует одному или нескольким (+
) последовательным символам, отличным от ([^...]
- выражение в скобках с отрицанием) букв и цифр ([:alnum:]
Класс символов POSIX соответствует буквам и цифрам).

Ну, вы могли бы также использовать (?:\W|_)+
. К сожалению, обычная конструкция регулярного выражения, такая как [\W_]+
, не будет работать, потому что \W
(и другие отрицательные сокращения, такие как \S
и \D
, являются недопустимыми внутри скобочных выражений. Более подробная информация доступна в руководстве :
В выражениях в скобках \d
, \s
и \w
теряют свои внешние скобки, а \D
, \S
и \W
являются недопустимыми. (Так, например, [a-c\d]
эквивалентно [a-c[:digit:]]
. Также, [a-c\D]
, что эквивалентно [a-c^[:digit:]]
, является недопустимым.)
Чтобы избавиться от конечных / ведущих пробелов, вы можете использовать trim
:
select trim(regexp_replace('hello_world!', '[^[:alnum:]]+', ' ', 'g'))