我需要在文本中标识{scope},例如源代码。 我只从一行开始,将扩展为搜索多行,并排除注释。我已经使用Pattern Matcher编写了代码,但我想批评如何改进这样的搜索。
String line = "{{outside{inside}{inside2}}};";
String scopeOf = "outside";
findscope(line,scopeOf);
private static void findscope(String line,
String scopeOf) {
int layer = 1;
Pattern p = Pattern.compile(scopeOf);
Matcher m = p.matcher(line);
if (m.find()) {
int scopestart = m.start();
int scopeEnd = Integer.MIN_VALUE;
m.usePattern(Pattern.compile("\\{|\\}"));
while (m.find()) {
String group = m.group();
if (group.equals("{")) {
layer++;
} else if (group.equals("}")) {
layer--;
}
if (layer == 0) {
scopeEnd = m.start();
break;
}
}
System.out.println("Scope of " + scopeOf + " starts at " + scopestart +
" finishes at " + scopeEnd);
}
}
答案 0 :(得分:1)
嗯,你正在使用错误的工具(假设你也在寻找嵌套的范围)
请注意,正则表达式(采用传统形式的正则表达式)代表正则表达式 - 这是一种描述Regular Language的方法。
然而,语言L = { all words with legal scopings }
是不规则的 - 因此无法通过正则表达式识别。
这个语言实际上是Conext Free Langauge,可以用Context Free Grammer来表示。
用于解析:
对于相对简单的语言(其中包括范围) - 确定性push-down automaton足以验证它们。
某些语言需要非确定性的下推自动机 - 这不是非常有效地创建的,但也有dynamic programming algorithm来解析它们。
作为旁注,有一些工具,例如JavaCC,您可以使用它们来解析(并生成代码/输出) - 看看它们,但如果您只是在寻找范围问题 - 这可能是一种矫枉过正。
编辑 - 伪代码:
curr <- 0
count <- 0 //integer imitates the stack for this simple usage
l <- string.length()
while (curr < l):
if string.charAt(curr) == '{':
count++;
else if string.charAt(curr) == '}':
if curr <= 0:
return ERROR;
count--;
curr++;
if count != 0:
return ERROR;
return SUCCESS;
注意,在这里我们可以使用一个整数来模仿堆栈,在这里增加基本上是push()而减少是pop()。