Не получается создать паттерн для REGEXP_LIKE для двух значений
Есть документ XML
<.........>
<RRRR>
<OfficeCode>12125589</OfficeCode>
<OfficeName>Офис 132</OfficeName>
</RRRR>
<DocumentNumber>1234-258 (копия)</DocumentNumber>
<DocumentDate>2000-01-01</DocumentDate>
<.................>
Сейчас поиск идет с двумя условиями:
AND TO_CLOB(message, 873,'text/xml') LIKE '%OfficeCode>12125589<%'
AND TO_CLOB(message, 873,'text/xml') LIKE '%DocumentNumber1234-258 (копия)<%'
Учу Oracle и хотел объединить два этих условия в один REGEXP_LIKE
Пробовал по разному и никак не хочет находиться. Через ИЛИ работает:
AND REGEXP_LIKE(TO_CLOB(message, 873,'text/xml'), 'OfficeCode>12125589<|DocumentNumber1234-258 (копия)<', 'm')
А вот как сделать И - не могу понять...
последнее что пробовал:
AND REGEXP_LIKE(TO_CLOB(mes.messagebody, 873,'text/xml'), '(OfficeCode>12125589<){1}(.*)(DocumentNumber1234-258 (копия)){1}', 'm')
AND REGEXP_LIKE(TO_CLOB(mes.messagebody, 873,'text/xml'), 'OfficeCode>12125589<(.*)DocumentNumber1234-258 (копия)', 'm')
Но так не раобтает. Не понимаю что не так и как это заставить работать(((
Ответы (2 шт):
Тут дело всего в одном моменте:
момент 0: просто опечатка, поэтому номер 0.
В последнем условии "DocumentNumber1234-258" вы пропустили ">" перед номером
Теперь к делу. Вы ипользуете выражение "любое количество любых символов"
.*
между искомыми подстроками, что понятно и логично. Проблема в том, что регулярки требуют почему-то указывать конец строки отдельно. Поэтому, чтоб сказать "вот любой символ прям вообще" для многострочного текста, нужно написать
(.|\s)*
что в переводе на человеческий означает "любое количество символов или концов строк". Такая вот особенность у регулярок этих.
Мой ответ:
'OfficeCode>12125589<(.|\s)*DocumentNumber>1234-258 (копия)'
Ваш вариант будет чудесно работать - если вставить ">" куда надо, конечно, - если вы превратите текст в одну строку
Но вопрос интересный, спасибо и +1 от меня
Можно обойтись и без регулярных выражений, а вместо них использовать XPath:
select a.doc.extract ('/RRRR/OfficeName/text()').getStringVal() OfficeName
from (
select xmlType (doc, 0).extract ('/Document/*') doc
from t) a
where a.doc.extract ('/RRRR/OfficeCode/text()').getStringVal() = '12125589'
and a.doc.extract ('/DocumentNumber/text()').getStringVal() = '1234-258 (копия)';
OFFICENAME
------------
Офис 132
Таблица с тестовыми данными:
create table t (id int, doc blob)
/
insert into t values (1, utl_raw.cast_to_raw ('
<Document>
<RRRR>
<OfficeCode>12125589</OfficeCode>
<OfficeName>Офис 132</OfficeName>
</RRRR>
<DocumentNumber>1234-258 (копия)</DocumentNumber>
<DocumentDate>2000-01-01</DocumentDate>
</Document>'));