Проблемы с регулярным выражением Java и чередование

У меня проблемы с получением регулярного выражения для работы. Я пытаюсь разобрать большой многострочный блок текста для определенных тегов XML. Причина, по которой я не анализирую это с библиотекой XML, однако, на самом деле она также является частью блока ESQL. Я использую следующую строку:

Pattern.compile(".*'(Invoice|Package|Mapping|Post)' AS STAGE.*(<(ESQL|ProcessInvoice)>.+)</(ESQL|ProcessInvoice)>).*", Pattern.DOTALL);

Моя проблема на самом деле в два раза:

  1. (Invoice|Package|Mapping|Post) раздел соответствует только Invoice, если я не удаляю Invoice из списка. Тогда это соответствует только картированию. Мне показалось странным, что Package находится в середине текстового блока (блоки упорядочены Invoice, Package, Mapping, Post в текстовом файле, с опцией Post, которая может быть необязательной, поэтому ее может даже не быть), а отображение - ближе к концу.

  2. <(ESQL|ProcessInvoice)> раздел на самом деле занимает ProcessInvoice блок (самый последний блок, последние три <ESQL> блоки в конце). Если я удалю (ESQL|ProcessInvoice) расстаться и просто сделать это <ESQL> как ни странно, он снова примет блок Package, а не первый блок для Invoice. Это по-прежнему остается проблемой, даже если я уменьшу это до одного из четырех предыдущих разделов (так что просто Invoice) без чередования нигде. Он пропустит первый раздел и возьмет второй.

Я признаю, что я не гуру регулярных выражений, но это выглядит довольно странно. Вызов.reset() для Matcher также не позволяет ему распознавать более ранний блок, а.find() находит только одно совпадение, вместо того, чтобы повторять все возможные совпадения.

--- Приложение --- Пример ввода следующим образом (отредактировано для содержимого):

CREATE COMPUTE MODULE Module_Name
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN       
    Header stuff,
    'Invoice' AS STAGE,
    Gibberish here
    '<Rule>
    <ESQL>
        ESQL Block 1
    </ESQL>
    <ESQL>
        ESQL Block 2
    </ESQL> 
    </Rule>' AS CONTENT);

    Header stuff,
    'Package' AS STAGE,
    Gibberish here
    '<Rule>
    <ESQL>
        ESQL Block 3
    </ESQL>
    </Rule>' AS CONTENT);

    Header stuff as well,
    'Mapping' AS STAGE,
    Gibberish here too
    '<ProcessInvoice>
        Another ESQL Block
    </ProcessInvoice>' AS CONTENT);
END;
END MODULE;

Предполагаемые группировки должны быть (соответственно):

  1. Счет-фактура
  2. пакет
  3. картографирование

И данные:

  1. ESQL Блок 1 ESQL Блок 2
  2. ESQL Block 3
  3. Еще один блок ESQL

Я должен упомянуть, что теперь я немного изменил свое регулярное выражение, и теперь оно выглядит следующим образом:

.*?'(Package|Invoice|Post)' AS STAGE.*?<Rule>(.+?)</Rule>.*?

Это чередование, кажется, работает сейчас для трех из четырех возможных разделов, но я думаю, что часть моей более ранней проблемы была попытка использовать <(ESQL|ProcessInvoice)> внутри другой группы. Попытка обойтись без <Rule>(.+?)</Rule>.*? и вместо этого сделать даже просто (<ESQL>.+?</ESQL>) не хочет работать сейчас.

1 ответ

Решение

Я бы поменял .* в .*? сделать это не жадным. Это, вероятно, поможет вам.

Но на самом деле вам лучше использовать синтаксический анализатор XML. Вы говорите, что не можете использовать анализатор XML, потому что XML встроен в другой текст. Затем я бы предложил вам извлечь весь блок XML (используя регулярное выражение или другой подходящий метод) и поместить его в анализатор XML.

Другие вопросы по тегам