2012-06-05 49 views
1

我在正则表达式中不强壮,所以任何帮助将不胜感激。RegEx for [“abc”,[“123”,“cba”]]

我需要解析这些字符串:

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

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

+0

你试图解析JSON?如果是这样,有Java的库可以做到这一点。 –

+0

@DelanAzabani不幸的是它不是JSON。 –

+0

不幸的是,这隐含地要求使用括号匹配(以确保您匹配正确的右括号),这通常不能用正则表达式来完成。但是,如果您知道括号最多可嵌套2或3层,则可以。是这样吗? – huon

回答

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, '#'); 
+0

非常感谢 - 它是完美的作品!但是,它是一回事,我忘了说。如果有这样的领域会怎么样:“文本,用逗号”?如何替换嵌套在引号中的逗号? –

+0

我刚刚编辑了代码以避免这些逗号。 – sp00m

2

看来你在你的输入中有递归,所以如果你有很多嵌套的[]正则表达式可能不是最好的解决方案。

为此,我认为使用简单的算法使用indexOf()substring()会更好/更简单。它也变得更加高效!

2

不幸的是,我不认为你可以用Java正则表达式来做到这一点。你在这里得到的是递归表达式。这种类型的语言对于基本的正则表达式是不可修正的(这正是java的实际所在)。

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

您可以检查以下答案中寻找灵感:java method for parsing nested expressions

相关问题