检查代码块是否在Java中正确嵌套?

问题描述:

如何验证如果码块,如在一个构建体:检查代码块是否在Java中正确嵌套?

{ 
    // Any amount of characters that aren't '{' or '}' 
} 

正确嵌套,优选具有正则表达式?

{} { 
    {} {} 
} // Properly nested 
{{ 
    {{}} 
} {} // Not properly nested 

As referred to from this thread,方法,如递归和平衡组不能在这里适用,因为regular expression constructs中不存在Java Pattern

+6

我不会使用这类问题的正则表达式。我可能会使用堆栈。 – 2014-09-01 15:02:34

+0

@HovercraftFullOfEels用户输入是一个String。在这种情况下有没有办法使用堆栈? – Unihedron 2014-09-01 15:04:05

+0

是的。我不是这方面的专家,但是不存在这样的解析器吗? – 2014-09-01 15:05:11

为什么使用正则表达式?我建议构建你自己的解析器。这样的事情:

public static boolean isProperlyNested(String toTest) { 
    int countOpen = 0; 
    for (char c : toTest.toCharArray()) { 
     if (c == '{') { 
      countOpen++; 
     } else if (c == '}') { 
      countOpen--; 
      if (countOpen < 0) return false; 
     } 
    } 
    return countOpen == 0; 
} 
+1

请注意,这是一个简化。例如,如何处理一段代码,其中在评论中隐藏了打开或关闭大括号;那就是顺便说一句堆栈或状态机进来的地方。 – 2014-09-01 15:17:12

+0

@MarkRotteveel堆栈实际上并没有更好的工作。只需包含一些布尔值,可以切换注释/字符串/字符/等,如果其中一个为真,则不要更改计数。 – Justin 2014-09-01 15:23:49

+0

对于这个特定的例子,堆栈可能是矫枉过正的(但是如果我想跟踪平衡括号**和**括号),尽管我会尽快选择枚举而不是一组布尔值来跟踪解析器的当前状态(我实际上只是为Jaybird做了这个工作,它允许将状态转换到状态:http://sourceforge.net/p/firebird/code/HEAD/tree/client-java/trunk/src/main/ org/firebirdsql/jdbc/escape/FBEscapedParser.java#l364)。 – 2014-09-01 15:32:55

我可以解决这个使用两个步骤,一个循环:

{ 
    String str1 = "{} {\n" + 
        " {} {}\n" + 
        "} // Properly nested", 
      str2 = "{{\n" + 
        " {{}}\n" + 
        "} {} // Not properly nested"; 
    final Pattern pattern = Pattern.compile("\\Q{}\\E"); 

    Matcher matcher = pattern.matcher(str1.replaceAll("[^{}]", "")); 
    while (matcher.find()) 
     matcher = pattern.matcher(str1 = matcher.replaceAll("")); 
    System.out.println(str1.isEmpty()); 

    matcher = pattern.matcher(str2.replaceAll("[^{}]", "")); 
    while (matcher.find()) 
     matcher = pattern.matcher(str2 = matcher.replaceAll("")); 
    System.out.println(str2.isEmpty()); 
} 

Here is an online code demoDemo与我在此处编写的代码略有不同,以便显示原始字符串方向。