RegEx for [“abc”,[“123”,“cba”]]

时间:2012-06-05 11:16:11

标签: java regex

我在正则表达方面不强,所以任何帮助都会受到赞赏。

我需要解析这样的字符串:

["text", "text", ["text",["text"]],"text"]

输出应该是(4个字符串):

text, text, ["text",["text"]], text

我尝试过这种模式(\\[[^\\[,^\\]]*\\])|(\"([^\"]*)\")

String data="\"aa\", \"aaa\", [\"bb\", [\"1\",\"2\"]], [cc]";
Pattern p=Pattern.compile("(\\[[^\\[,^\\]]*\\])|(\"([^\"]*)\")");

但输出是(输出中的引号不是那么关键):

"aa", "aaa", "bb", "1", "2", [cc]

如何提高我的正则表达式?

3 个答案:

答案 0 :(得分:3)

我不确定正则表达式是否可以自己做那种事情。这是一种方法:

// data string
String input = "\"aa\", \"a, aa\", [\"bb\", [\"1\", \"2\"]], [cc], [\"dd\", [\"5\"]]";
System.out.println(input);

// char that can't ever be within the data string
char tempReplacement = '#';
// escape strings containing commas, e.g "hello, world", ["x, y", 42]
while(input.matches(".*\"[^\"\\[\\]]+,[^\"\\[\\]]+\".*")) {
    input = input.replaceAll("(\"[^\"\\[\\]]+),([^\"\\[\\]]+\")", "$1" + tempReplacement + "$2");
}
// while there are "[*,*]" substrings
while(input.matches(".*\\[[^\\]]+,[^\\]]+\\].*")) {
    // replace the nested "," chars by the replacement char
    input = input.replaceAll("(\\[[^\\]]+),([^\\]]+\\])", "$1" + tempReplacement + "$2");
}

// split the string by the remaining "," (i.e. those non nested)
String[] split = input.split(",");

List<String> output = new LinkedList<String>();
for(String s : split) {
    // replace all the replacement chars by a ","
    s = s.replaceAll(tempReplacement + "", ",");
    s = s.trim();
    output.add(s);
}

// syso
System.out.println("SPLIT:");
for(String s : output) {
    System.out.println("\t" + s);
}

输出:

"aa", "a, aa", ["bb", ["1", "2"]], [cc], ["dd", ["5"]]
SPLIT:
    "aa"
    "a, aa"
    ["bb", ["1","2"]]
    [cc]
    ["dd", ["5"]]

PS:代码似乎很复杂'因为评论。这是一个更简洁的版本:

public static List<String> split(String input, char tempReplacement) {
    while(input.matches(".*\"[^\"\\[\\]]+,[^\"\\[\\]]+\".*")) {
        input = input.replaceAll("(\"[^\"\\[\\]]+),([^\"\\[\\]]+\")", "$1" + tempReplacement + "$2");
    }
    while(input.matches(".*\\[[^\\]]+,[^\\]]+\\].*")) {
        input = input.replaceAll("(\\[[^\\]]+),([^\\]]+\\])", "$1" + tempReplacement + "$2");
    }
    String[] split = input.split(",");
    List<String> output = new LinkedList<String>();
    for(String s : split) {
        output.add(s.replaceAll(tempReplacement + "", ",").trim());
    }
    return output;
}

呼叫:

String input = "\"aa\", \"a, aa\", [\"bb\", [\"1\", \"2\"]], [cc], [\"dd\", [\"5\"]]";
List<String> output = split(input, '#');

答案 1 :(得分:2)

您的输入中似乎有递归,因此如果您有许多嵌套的[]正则表达式可能不是最佳解决方案。

为此,我认为使用indexOf()substring()使用简单算法要好得多/容易得多。它的效率也更高了!

答案 2 :(得分:2)

不幸的是,我不认为你可以用Java正则表达式做到这一点。你在这里有的是递归表达式。这种类型的语言不能修改为基本正则表达式(这是java Pattern实际上是什么)。

但为这种语言编写一个小的递归下降解析器并不难。

您可以查看以下答案获取灵感:java method for parsing nested expressions