Не получается создать паттерн для 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 шт):

Автор решения: ekochergin

Тут дело всего в одном моменте:

момент 0: просто опечатка, поэтому номер 0.

В последнем условии "DocumentNumber1234-258" вы пропустили ">" перед номером

Теперь к делу. Вы ипользуете выражение "любое количество любых символов"

.* 

между искомыми подстроками, что понятно и логично. Проблема в том, что регулярки требуют почему-то указывать конец строки отдельно. Поэтому, чтоб сказать "вот любой символ прям вообще" для многострочного текста, нужно написать

(.|\s)* 

что в переводе на человеческий означает "любое количество символов или концов строк". Такая вот особенность у регулярок этих.

Мой ответ:

'OfficeCode>12125589<(.|\s)*DocumentNumber>1234-258 (копия)'

Ваш вариант будет чудесно работать - если вставить ">" куда надо, конечно, - если вы превратите текст в одну строку

Но вопрос интересный, спасибо и +1 от меня

→ Ссылка
Автор решения: 0xdb

Можно обойтись и без регулярных выражений, а вместо них использовать 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>'));
→ Ссылка