сопоставить что-либо с конкретным символом, НО не те, которые имеют что-то перед конечным символом - PullRequest
0 голосов
/ 29 января 2019

У меня есть следующая строка:

aaa'dd? 'D'xxx'

Разделитель:

'

, но если перед ним стоит

?

, его следует рассматривать не как разделитель, а как буквальный (escape-символ для разделителя).Результат, который я хочу отобразить:

aaa

dd'd

xxx

В данный момент я использую [^ '] +, который не учитывает экранирующий символ (?).

Можете ли вы мне помочь, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 29 января 2019

Если вы хотите сделать это, не заменяя шаблон ?' фиксированным фиктивным символом - будь то '#' или что-то еще, что, как вы уверены, никогда не появится, - тогда вы можете использовать шаблон регулярного выражения, например так:

-- bind variable for sample value
var str varchar2(20);
exec :str := q'[aaa'dd?'d'xxx']';

select regexp_substr(:str, '((.*?[^?])*?)(''|$)', 1, level, null, 1) as result
from dual
connect by level < regexp_count(:str, '((.*?[^?])*?)(''|$)');

RESULT              
--------------------
aaa
dd?'d
xxx

и затем вы можете просто применить простую замену:

select replace(
  regexp_substr(:str, '((.*?[^?])*?)(''|$)', 1, level, null, 1),
   '?''',
   '''') as result
from dual
connect by level < regexp_count(:str, '((.*?[^?])*?)(''|$)');

RESULT              
--------------------
aaa
dd'd
xxx

Если у вас есть два соседних неэкранированных разделителя, вы получаете нулевой элемент из этой позиции (этого не произошло)с более ранней версией шаблона регулярных выражений):

exec :str := q'[aaa''dd?'d'xxx']';
-- just to make them more visible...
set null (null)

select replace(
  regexp_substr(:str, '((.*?[^?])*?)(''|$)', 1, level, null, 1),
   '?''',
   '''') as result
from dual
connect by level < regexp_count(:str, '((.*?[^?])*?)(''|$)');

RESULT              
--------------------
aaa
(null)
dd'd
xxx
0 голосов
/ 29 января 2019

Простой вариант - заменить оскорбительную строку чем-то другим;например, я использовал #.Для окончательного результата замените его одинарной кавычкой, '.

SQL> with test (col) as
  2    (select q'[aaa'dd?'d'xxx']' from dual),
  3  inter as
  4    (select replace(col, '?''', '#') icol
  5     from test
  6    )
  7  select replace(regexp_substr(icol, '[^'']+', 1, level), '#', '''') result
  8  from inter
  9  connect by level <= regexp_count(icol, '''');

RESULT
-------------
aaa
dd'd
xxx
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...