【问题标题】:Split string by all spaces except those in brackets [duplicate]除括号中的空格外的所有空格分割字符串[重复]
【发布时间】:2012-10-14 17:14:47
【问题描述】:

可能重复:
Split a String based on regex

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

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

【问题讨论】:

  • @artbristol 非常好的评论。
  • @artbristol 是的,他们可以,我不希望在任何一组括号内发生拆分。我进行了编辑以包含另一个示例。
  • @A.R.S,那么你不能用正则表达式来做。是时候编写解析器了。
  • 这是第三个完全重复的问题..thisthis

标签: java regex


【解决方案1】:

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

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

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

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

【讨论】:

  • 它无法编译 - 我收到“格式错误的正则表达式”错误
  • 嗯,java需要[在字符类中转义吗?谢谢提示
  • @Jimmy:我只是在转义中编辑,之前是"…[^[]…"
  • @Bergi 是的 - 更正后的版本有效! +1
  • @Bergi 有什么方法可以同时为[]{} 括号(非嵌套)工作?例如a b {c d} [e f] 将变为 a, b, {c d}, [e f]
【解决方案2】:

你不能用单个正则表达式来做到这一点,因为它不能匹配开/关大括号和处理嵌套大括号。

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

所以我宁愿建议你自己编写几行代码,绝对可以处理所有情况。

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

【讨论】:

  • 你可以在正则表达式中做到这一点..nd它工作正常..
  • [[xx], [y]] z t [z [x] y] 继续。
  • 做到了..2次here及以上..
  • 在 c# 中有效,但在 java 中无效...感谢 java 对lookbehind 的有限支持
  • 正则表达式带有回顾/展望和其他受 perl 启发的东西与正则表达式本身无关。这个问题与 Java 有关,我不太关心 C# 或 Perl 的作用。
【解决方案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;
}

【讨论】:

  • 你可以在正则表达式中做到这一点。你不需要解析器
  • 如何使用正则表达式管理多个嵌套的 []?
【解决方案4】:

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

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

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

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

rule4 -> rule1 | rule3

【讨论】:

    【解决方案5】:

    对于非嵌套

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

    嵌套使用([] 内 [])

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

    【讨论】:

    • 编译器抱怨第二个正则表达式中存在无效的转义序列。
    • 第一个正则表达式也是如此。
    • @A.R.S.尝试删除转义字符 \
    • @Anirudha 我设法让第一个正则表达式工作,第二个仍然有问题。
    • @Anirudha 对于第二个正则表达式:java.util.regex.PatternSyntaxException: Look-behind group does not have an obvious maximum length near index 11
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 2016-12-26
    • 1970-01-01
    • 2022-10-13
    • 2015-09-03
    • 1970-01-01
    • 2012-02-14
    相关资源
    最近更新 更多