【问题标题】:Java regex for balanced parantheses平衡括号的Java正则表达式
【发布时间】:2017-07-11 08:04:05
【问题描述】:

我有一个类似的字符串:

If ({{SQL}}.Employee.Title starts with 'Production') 
and  (substring of {{SQL}}.Employee.Title from '27' for '2' is not '30') 
and ({{SQL}}.Employee.HireDate is greater than or equal to '2000-01-01 00:00:00.000')  
then Pull  {{SQL}}.Title,  {{SQL}}.HireDate from Employee

从这个表达式中,我想知道Java语言中圆括号是否正确平衡。

一种方法是创建一个计数器变量,一旦我找到左括号,它就会增加,遇到右括号时会减少它。根据结果​​,我可以决定结果。

但这对于像 () 这样的字符串没有帮助,即括号之间没有任何字母数字字符。

有什么方法可以确定圆括号是否平衡并且这些括号之间应该有字母数字字符。 如果括号为空,即左括号和右括号之间没有字符,则应该抛出错误。

【问题讨论】:

  • 不要使用正则表达式,它会变得混乱。使用Stack
  • 使用堆栈,如何识别括号内的字母数字字符。
  • 想想吧。如果你得到一个左括号,则将它压入堆栈并将标志设置为 true。因此,读取的下一个元素不应是右大括号(错误)。此外,在左大括号之后读取的所有元素都应该是字母数字(检查stackoverflow.com/questions/12831719/…
  • 应该使用正则表达式来验证单词在正则语言中是否有效。常规语言不需要堆栈来验证。带有大括号奇偶校验的语言需要一个堆栈,因此正则表达式是一个非常糟糕的工具。

标签: java regex


【解决方案1】:

您需要一个类似于下面的代码。它确实使用堆栈来跟踪打开/关闭括号的数量+记住最后一个字符出现是什么以便跟踪空括号:

    String test = "{TEST}(A){";

    Stack<Integer> stack = new Stack<>();
    boolean lastCharIsParantheses = false;
    for (char c : test.toCharArray()) {
        switch (c) {
            case '{':
            case '(': {
                stack.push(1);
                lastCharIsParantheses = true;
                continue;
            }
            case '}':
            case ')':
                stack.pop();
                if (lastCharIsParantheses) {
                    throw new RuntimeException("Empty parantheses");
                }
        }
        lastCharIsParantheses = false;
    }
    if (!stack.empty()) {
        throw new RuntimeException("Not matching number of opened/closed parantheses");
    }

【讨论】:

  • 用 RunTimeException 替换 Exception 并改进开关。您还可以解释一下这段代码的作用吗?请参阅How to Answer。我还是喜欢这个答案
猜你喜欢
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 2014-09-26
相关资源
最近更新 更多