Java正则表达式和交替的麻烦

时间:2012-03-15 18:44:36

标签: java regex multiline alternation

我正在努力让正则表达式工作。我正在尝试为某些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),没有任何交替。它将跳过第一部分并进入第二部分。

我承认我不是正则表达式大师,但这似乎是一种奇怪的行为。在Matcher上调用.reset()也不会使它识别出前一个块,并且.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. 映射
  4. 数据:

    1. ESQL Block 1 ESQL Block 2
    2. ESQL Block 3
    3. 另一个ESQL块
    4. 我应该提一下,我现在稍微改变了我的正则表达式,现在它如下:

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

      这种交替似乎现在可用于四个可能的部分中的三个部分,但我相信我之前遇到的部分麻烦是试图在另一个团体中使用<(ESQL|ProcessInvoice)>。尝试不使用<Rule>(.+?)</Rule>.*?,而只是(<ESQL>.+?</ESQL>),但现在不想工作。

1 个答案:

答案 0 :(得分:1)

我将.*更改为.*?以使其不贪婪。这可能会对你有所帮助。

但实际上你最好使用XML解析器。您说您不能使用XML解析器,因为XML嵌入在其他文本中。然后我建议您提取整个XML块(使用正则表达式或其他适当的方法)并将其放入XML解析器中。