【问题标题】:Specific splitting of string by brackets用括号具体分割字符串
【发布时间】:2013-10-11 14:11:23
【问题描述】:

我想按以下方式拆分字符串:

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]]

有什么方法可以使用正则表达式以我想要的方式拆分字符串?

【问题讨论】:

  • 括号可以任意嵌套吗?
  • 检查this blog post。这个想法是在空白处拆分,然后是平衡的开括号和右括号。
  • @RohitJain:不幸的是,这个技巧在这里行不通,因为 OP 嵌套了方括号。
  • @anubhava 哦!对,错过了那个。
  • @Bec 可能会举例说明正则表达式输出/匹配应该是什么,我不清楚您的期望是什么

标签: java regex string split


【解决方案1】:

这很有效,虽然不是特别漂亮,并且在没有来自 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;
        }
    }        
}

将分割后的字符串写入标准输出;随意添加到您喜欢的容器中。

【讨论】:

  • 谢谢芭丝谢芭!字符串“sum 1 2”是否有理由只返回一个带有“sum”而不是{“sum”、“1”、“2”}的列表?
  • @Bec:是的;我就是这样解释这个问题的。 [sum 1 2] 不会分开它。
  • 对不起,我的意思是 1 和 2 似乎在代码中丢失了?如果我在“sum 1 2”上运行代码,它只会返回一个包含“sum”的列表。
  • 我已经修改了。不过现在有点乱了。
【解决方案2】:

有什么方法可以使用正则表达式以我想要的方式拆分字符串?

不,没有。正则表达式(如果匹配)返回由() 包围的字符串和子字符串,或者如果您使用全局标志,则返回所有完整匹配项的列表。您不会得到其他匹配项的子项的嵌套列表。

将它与 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,如果需要更多说明,请发表评论。 :) 希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多