Проблемы с регулярным выражением Java и чередование - PullRequest
1 голос
/ 15 марта 2012

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

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

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

  1. Раздел (Invoice|Package|Mapping|Post) соответствует только Счету, если я не удаляю Счет из списка. Тогда это соответствует только картированию. Мне показалось странным, что 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 Блок 3
  3. Другой блок ESQL

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

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

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

1 Ответ

1 голос
/ 15 марта 2012

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

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

...