1

我在让正则表达式工作时遇到了麻烦。我正在尝试为某些 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. 映射

和数据:

  1. ESQL 块 1 ESQL 块 2
  2. ESQL 块 3
  3. 另一个 ESQL 块

我应该提到我现在稍微改变了我的正则表达式来解释,现在如下:

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

这种交替似乎现在适用于四个可能的部分中的三个,但我相信我之前的部分问题是试图<(ESQL|ProcessInvoice)>在另一个组内部使用。试图不做<Rule>(.+?)</Rule>.*?,而是做,甚至只是(<ESQL>.+?</ESQL>)不想现在工作。

4

1 回答 1

1

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

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

于 2012-03-15T18:50:24.913 回答