почему не удается сопоставить символ ']' с regexp_like в оракуле?

Когда я ввожу эти SQL-запросы, они возвращают результат 1:

sql 1:

select 1 from dual where regexp_like('R[23','^[[0-9a_zA-Z]+$');

возвращает 1

sql 2:

select 1 from dual where regexp_like('[]','^\\[\\]$');

возвращает 1


Но когда я ввожу этот SQL, он не может вернуть результат с 1

sql 3:

select 1 from dual where regexp_like('R23]','^[0-9a_zA-Z\\]]+$');

возвращает null


person WinLXY    schedule 12.05.2020    source источник
comment
SQL 2 не выводит 1. Вы хотите, чтобы select 1 from dual where regexp_like('[]','^\[]$'); содержал только один escape-символ \ , чтобы предотвратить запуск выражения в квадратных скобках. db‹›fiddle.   -  person MT0    schedule 12.05.2020
comment
Вот ответ.   -  person Wiktor Stribiżew    schedule 12.05.2020


Ответы (1)


Поставьте закрывающую квадратную скобку первой в регулярном выражении и не экранируйте ее:

SELECT 1
FROM   dual
WHERE  regexp_like( 'R23]', '^[]0-9a-zA-Z]+$');

Вы также хотите a-z, а не a_z.

Из документации Oracle:

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

Чтобы указать правую скобку (]) в выражении скобок, поместите ее первой в списке (после начального циркумфлекса (^), если он есть).

Чтобы указать дефис в выражении в квадратных скобках, поместите его первым в списке (после начального циркумфлекса (^), если он есть), последним в списке или в качестве конечной точки диапазона в выражении диапазона.

Ваше выражение (после исправления _ на -):

SELECT  1
FROM    DUAL
WHERE   regexp_like('R23]','^[0-9a-zA-Z\\]]+$');

Сопоставляется, чтобы увидеть, есть ли символ, который соответствует одному из символов 0123456789abcdefghiklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\\ в начале строки (в регулярном выражении нет escape-символа, поэтому \ рассматривается как часть группы символов для сопоставления), а затем следует один или несколько символов ], а затем конец строки.

So:

SELECT  1
FROM    DUAL
WHERE   regexp_like('\]]]]]]]]]]','^[0-9a-zA-Z\\]]+$');

Выходы 1

db‹›fiddle

person MT0    schedule 12.05.2020