【问题标题】:Check if code blocks are nested correctly in Java?检查代码块是否在 Java 中正确嵌套?
【发布时间】:2014-10-25 20:12:27
【问题描述】:

如何验证代码块,如在构造中:

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

是否正确嵌套,最好使用正则表达式?

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

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

【问题讨论】:

  • 我不会使用正则表达式来解决这类问题。我可能会使用堆栈。
  • @HovercraftFullOfEels 用户输入是String。有没有办法在这种情况下使用堆栈?
  • 是的。我不是这方面的专家,但不是已经存在解析器来处理这类事情吗?

标签: java regex string matching regex-negation


【解决方案1】:

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

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;
}

【讨论】:

  • 请注意,这是一种简化。例如,如何处理一段代码,其中左大括号或右大括号隐藏在注释中;顺便说一句,堆栈或状态机进来。
  • @MarkRotteveel 堆栈实际上并没有更好的工作。只需包含一些为 cmets/strings/chars/etc 切换的布尔值,如果其中一个为真,则不要更改计数。
  • 对于这个特定的例子来说,堆栈可能是多余的(但是如果我想跟踪平衡的大括号 括号怎么办),尽管我更愿意选择枚举而不是集合用于跟踪解析器当前状态的布尔值(我实际上是为 Jaybird 做的;它允许将状态切换留给状态本身:sourceforge.net/p/firebird/code/HEAD/tree/client-java/trunk/src/…)。
  • @MarkRotteveel 是的,这是真的;存储字符的堆栈对于使用多种类型的匹配字符进行测试是一个好主意。
【解决方案2】:

我可以通过循环使用两个步骤来解决这个问题:

{
    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 与我在这里写的代码略有不同,以显示原始字符串方向。

【讨论】:

    猜你喜欢
    • 2016-11-25
    • 1970-01-01
    • 2023-03-17
    • 2015-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多