10

可能重复:
根据正则表达式拆分字符串

我从来都不是正则表达式大师,所以我需要你的帮助!我有一个这样的字符串:

String s = "a [b c] d [e f g]";

我想使用空格作为分隔符来分割这个字符串——但我不想分割出现在[]括号内的空格。所以,从上面的例子中,我想要这个数组:

{"a", "[b c]", "d", "[e f g]"}

关于可以结合使用什么正则表达式split来实现这一目标的任何建议?


这是另一个例子:

"[a b] c [[d e] f g]"

变成

{"[a b]", "c", "[[d e] f g]"}
4

5 回答 5

10

我认为这应该可行,使用负前瞻- 它不匹配没有左括号的右括号之前的空格:

"a [b c] d [e f g]".split("\\s+(?![^\\[]*\\])");

对于嵌套括号,您将需要编写解析器,正则表达式无法承受无限级别,并且对于超过一两个级别来说过于复杂。例如,我的表达失败了

"[a b [c d] e] f g"
于 2012-10-14T17:22:26.457 回答
4

您不能使用单个正则表达式来做到这一点,仅仅是因为它无法匹配打开/关闭大括号并处理嵌套大括号。

正则表达式不是图灵完备的,所以即使它看起来可以工作,也会有失败的情况。

所以我宁愿建议编写你自己的几行代码,这肯定会处理所有情况。

您可以为JavaCCAntLR创建非常简单的语法,或者使用简单的基于堆栈的解析器。

于 2012-10-14T17:35:26.613 回答
3

正如在其他答案中所说,您需要一个解析器。这是一个与以前的正则表达式解决方案一起失败的字符串。

"[a b] c [a [d e] f g]"

编辑:

public static List<String> split(String s){
    List<String> l = new LinkedList<String>();
    int depth=0;
    StringBuilder sb = new StringBuilder();
    for(int i=0; i<s.length(); i++){
        char c = s.charAt(i);
        if(c=='['){
            depth++;
        }else if(c==']'){
            depth--;
        }else if(c==' ' && depth==0){
            l.add(sb.toString());
            sb = new StringBuilder();
            continue;
        }
        sb.append(c);
    }
    l.add(sb.toString());

    return l;
}
于 2012-10-14T17:39:10.737 回答
0

如果我正确理解了您的问题,那么答案可能是遵循规则 4。

rule1 -> ((a-z).(\w))*.(a-z)

rule2 -> ([).rule1.(])

rule3 -> ([).(rule1.(\w))*.rule2.((\w).rule1)*.(])

rule4 -> rule1 | rule3
于 2012-10-14T17:21:46.660 回答
-1

对于非嵌套

\\s+(?![^\\[]*\\])

FOR嵌套([]内[])

(?<!\\[[^\\]]*)\\s+(?![^\\[]*\\])
于 2012-10-14T17:27:47.297 回答