如何使用正则表达式在LaTeX中查找嵌套标签



我正试图用java从LaTeX源代码中提取定理。我的代码几乎可以工作,但有一个测试用例失败了——嵌套定理。

@Test
public void testNestedTheorems() {
    String source = "\begin{theorem}" +
                    "this is the outer theorem" +
                    "\begin{theorem}" +
                    "this is the inner theorem" +
                    "\end{theorem}" +
                    "\end{theorem}";
    LatexTheoremProofExtractor extractor = new LatexTheoremProofExtractor(source);
    extractor.parse();
    ArrayList<String> theorems = extractor.getTheorems();
    assertNotNull(theorems);
    assertEquals(2, theorems.size()); // theorems.size() is 1
    assertEquals("this is the outer theorem", theorems.get(0)); 
    assertEquals("this is the inner theorem", theorems.get(1)); 
}

这是我的定理提取器,它被LatexTheoremProofExtractor#parse:调用

private void extractTheorems() {
    // If this has been called before, return
    if(theorems != null) {
        return;
    }
    theorems = new ArrayList<String>();
    final Matcher matcher = THEOREM_REGEX.matcher(source);
    // Add trimmed matches while you can find them
    while (matcher.find()) {
        theorems.add(matcher.group(1).trim());
    }   
}

CCD_ 2定义如下:

private static final Pattern THEOREM_REGEX = Pattern.compile(Pattern.quote("\begin{theorem}")
                                                    + "(.+?)" + Pattern.quote("\end{theorem}"));

有人对处理嵌套标签有什么建议吗?

如果你只想匹配双嵌套的theorems,你可以为它写一个显式正则表达式。我想它会是这样的。

Pattern.compile(
      Pattern.quote("\begin{theorem}")
        + "("
            + "(.+?)"
            + Pattern.quote("\begin{theorem}")
                + "(.+?)"
            + Pattern.quote("\end{theorem}")
        + ")*"
     + Pattern.quote("\end{theorem}"));

(这段代码应该会给你这个想法,但它还没有经过测试,可能不像写的那样工作。这不是我想说的。)

对于三重嵌套,您可以继续执行此操作,对于所需的任何固定数量的嵌套,依此类推。不用说,它很快就会变得相当尴尬。

然而,如果您的目标是匹配任意深度嵌套,那么根本不可能使用正则表达式。问题是,您想要匹配的语言不是正则的(但与上下文无关)。上下文无关语言严格来说比正则语言更强大,正则表达式只能精确匹配正则语言。一般来说,如果你想匹配一种上下文无关的语言,你需要构造一个下推自动机。

进一步阅读:

  • 乔姆斯基层次
  • "现在你有两个问题"是什么意思

最新更新