2015-11-01 16 views
0

我試圖從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()); 
    } 
} 

THEOREM_REGEX定義如下:

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

沒有人有建議處理嵌套的標籤?

+0

隨着一個正則表達式?你不能。 – immibis

回答

1

如果你只想匹配雙重嵌套的theorem s,你可以寫下一個明確的正則表達式。我想它會看起來像這樣。

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

(此代碼應該給你的想法,但它是未經測試的可能並不像書面工作。這不是我想要的地步。)

您可以繼續此爲三重嵌套等等你想要的任何固定數量的嵌套。不用說,它很快就會變得相當尷尬。

但是,如果您的目標是匹配任意深度嵌套,那麼根本不可能用來處理正則表達式。問題是你想要匹配的語言不是常規的(但是上下文無關)。上下文無關語言比常規語言嚴格得多,而正則表達式只能精確匹配常規語言。一般來說,如果您想匹配上下文無關的語言,您需要構建一個下推式自動機。

延伸閱讀:

+0

我想知道多久才能得到「兩個問題」的講座。 ;)但是,很感激。我想是時候開始重新設計了。 – erip

相關問題