1

我不擅长正则表达式,所以任何帮助将不胜感激。

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

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

如何改进我的正则表达式?

4

3 回答 3

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, '#');
于 2012-06-05T11:52:42.257 回答
2

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

为此,我认为使用简单算法更好/更容易使用indexOf()and substring()。它也更高效!

于 2012-06-05T11:32:29.497 回答
2

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

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

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

于 2012-06-05T11:34:15.043 回答