特定情况下通过括号分割字符串

4

我希望按照以下方式拆分字符串:

String s = "dotimes [sum 1 2] [dotimes [sum 1 2] [sum 1 3]]"

结果:
{"dotimes", "[sum 1 2]", "[dotimes [sum 1 2] [sum 1 3]]" 

我尝试使用这个正则表达式:
s.split("\\s(?=\\[)|(?<=\\])\\s")

但这将导致以下结果:
dotimes

[sum 1 2]

[dotimes

[sum 1 2]

[sum 1 3]]

有没有办法使用正则表达式按照我想要的方式拆分字符串?

括号可以任意嵌套吗? - arshajii
请查看这篇博客文章。其思路是在平衡的开括号和闭括号后跟随空格进行分割。 - Rohit Jain
@RohitJain:不幸的是,那个技巧在这里行不通,因为OP有嵌套的方括号。 - anubhava
@Bec 可以举个正则表达式输出/匹配的例子吗?我不清楚你的期望是什么。 - gwillie
@gwillie,我想按照外部括号分割字符串,同时忽略内部括号。所以我希望"[sum 10 10] [sum 3 3]"变成{[sum 10 10],[sum 3 3]}。但是当涉及到嵌套括号时,这就变得更加棘手了。 - Bec
显示剩余4条评论
2个回答

0
有没有办法使用正则表达式以我想要的方式拆分字符串? 没有,如果匹配,正则表达式会返回您用()包围的字符串和子字符串,或者如果使用全局标志,则返回所有完整匹配的列表。您不会得到其他匹配项的子级项目的嵌套列表。 将其与Java结合使用可以解决问题。我不知道Java,但我会试着用类似Java的代码来解释。
Array match_children (Array input) {
    Array output;

    foreach (match in input) {
        // The most important part!
        // The string starts with "[", so it is the beginning of a new nest
        if (match.startsWith("[")) {
            // Use the same ragex as below
            Array parents = string.match(matches 'dotimes' and all between '[' and ']');

            // Now, call this same function again with the 
            match = match_children(parents);
            // This stores an array in `match`
        }

        // Store match in output list
        output.push(match);

    }

    return output;
}

String string = "dotimes [sum 1 2] [dotimes [sum 1 2] [sum 1 3]]";
// "dotimes [sum 1 2] [dotimes [sum 1 2] [sum 1 3]]"

Array parents = string.match(matches 'dotimes' and all between '[' and ']');
// "dotimes", "[sum 1 2]", "[dotimes [sum 1 2] [sum 1 3]]"
// Make sure to use a global flag

Array result = match_children(Array input);
// dotimes
// [
//      sum 1 2
// ]
// [
//  dotimes
//  [
//      sum 1 2
//  ]
//  [
//      sum 1 3
//  ]
// ]

再一次声明,我不熟悉Java,如需更多解释,请评论区留言。 :) 希望这可以帮到你。


0

这个方法可行,虽然不是特别优美,在没有 OP 的正式语法的情况下,可能在泛化方面表现不佳。

{
    //String s = "sum 1 2";
    String s = "dotimes [sum 1 2] [dotimes [sum 1 2] [sum 1 3]]";
    int depth = 0;
    int pos = 0;        
    for (int c = 0; c <= s.length(); ++c){
        switch (c == s.length() ? ' ' : s.charAt(c)){
        case '[':
            if (++depth == 1){
                pos = c;
            }
            break;
        case ' ':
            if (depth == 0){
                String token = s.substring(pos, c == s.length() ? c : c + 1);
                if (!token.matches("\\s*")){ /*ingore white space*/
                    System.out.println(token);
                }                            
                pos = c + 1;
            }
            break;
        case ']':
            if (--depth == 0){
                String token = s.substring(pos, c + 1);
                if (!token.matches("\\s*")){ /*ingore white space*/
                    System.out.println(token);
                }                                                        
                pos = c + 1;
            }
        break;
        }
    }        
}

它将分割后的字符串写入标准输出;您可以根据需要将其添加到您喜欢的容器中。


谢谢Bathsheba!为什么字符串“sum 1 2”返回的只是一个包含“sum”的列表,而不是{"sum", "1", "2"}? - Bec
@Bec:是的,那就是我理解的问题。[sum 1 2]不会将它们分开。 - Bathsheba
抱歉,我的意思是在代码中似乎丢失了1和2?如果我在“sum 1 2”上运行代码,它只返回一个包含“sum”的列表。 - Bec
我已经修改了。现在有点乱了。 - Bathsheba

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接