我试图用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}"));有人有处理嵌套标记的建议吗?
发布于 2015-11-01 23:20:05
如果您只想匹配双重嵌套的theorem,您可以为它编写一个显式的正则表达式。我想它看起来会像这样。
Pattern.compile(
Pattern.quote("\\begin{theorem}")
+ "("
+ "(.+?)"
+ Pattern.quote("\\begin{theorem}")
+ "(.+?)"
+ Pattern.quote("\\end{theorem}")
+ ")*"
+ Pattern.quote("\\end{theorem}"));(这段代码应该给你这个想法,但它是未经测试的,很可能不像写的那样工作。这不是我想说的。)
对于任意固定数量的嵌套,您可以继续进行三重嵌套,等等。不用说,它很快就会变得相当尴尬。
但是,如果您的目标是匹配任意的深嵌套,那么使用正则表达式是不可能的。问题是,您想要匹配的语言不是常规的(而是上下文无关的)。上下文无关语言比普通语言更强大,正则表达式只能精确地匹配正则语言。通常,如果您想要匹配上下文无关的语言,则需要构造一个下推自动机。
进一步读:
https://stackoverflow.com/questions/33468255
复制相似问题