java:如何将此字符串转换为ArrayList?

String text = '[["item1","item2","item3"], ["some", "item"], ["far", "out", "string"]]'; 

我想迭代每个单独的ArrayList。 我不知道如何将该字符串转换为适当的ArrayList对象。

这个语法看起来像是JSON的一个子集,我猜想客户端实际上将它编码为JSON。 假设这是真的,最简单的方法是使用现成的JSON解析器和一些简单的Java代码将结果对象转换为代码所需的forms。

当然,您可以手动实现自己的解析器,但它可能不值得付出努力,特别是如果您必须处理字符串转义,空格中可能的可变性等等。 不要忘记,如果您实现自己的解析器,您需要执行unit testing以确保它在所有预期的有效输入范围内工作,以及无效输入。 (测试无效输入的情况很重要,因为如果某些黑客发送包含错误输入的请求,您不希望服务器崩溃。)

在继续之前,您确实需要确认客户端发送给您的确切语法。 仅仅看一个例子就不会回答这个问题。 您需要一个文档来指定语法,或者您需要查看客户端/应用程序源代码。

这是一个简单的解析器,它应该处理所有类型的滥用嵌套,并且对单引号和双引号都很健壮 – 但是如果你把它们混合它就不在乎'test"被视为等同于"test"

编辑:添加评论,现在它处理字符串中的转义引号。 (现在改进了字符串令牌处理function)

 import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; public class StringToList { public static void main(String[] args) throws IOException{ StringReader sr = new StringReader("[[\"it\\\"em1\", \"item2\",\"item3\"], [\"some\",\"item\"], [\"far\",\"out\",\"string\"]]"); System.out.println(tokenize(sr)); } @SuppressWarnings({ "rawtypes", "unchecked" }) public static List tokenize(StringReader in) throws IOException{ List stack = new ArrayList(); int c; while((c = in.read()) != -1){ switch(c){ case '[': // found a nested structure, recurse.. stack.add(tokenize(in)); break; case ']': // found the end of this run, return the // current stack return stack; case '"': case '\'': // get the next full string token stack.add(stringToken(in)); break; } } // we artificially start with a list, though in principle I'm // defining the string to hold only a single list, so this // gets rid of the one I created artifically. return (List)stack.get(0); } public static String stringToken(StringReader in) throws IOException{ StringBuilder str = new StringBuilder(); boolean escaped = false; int c; outer: while((c = in.read()) != -1){ switch(c){ case '\\': escaped = true; break; case '"': case '\'': if(escaped){ escaped = false; }else{ break outer; } default: str.append((char)c); } } return str.toString(); } } 

只是几个注释:这不会强制你的语法是正确的,所以如果你用引号做一些蠢事,就像我描述的那样,它仍然可以解析为(un)预期。 此外,我不强制使用逗号,你甚至不需要引号之间的空格,所以["item1""item2"]使用此解析器与["item1", "item2"]一样有效,但也许更奇怪的是,这件事也应该处理["item1"asdf"item2"]忽略asdf

由于您使用的字符串看起来像JSON,我只会使用JSON解析器。 最简单的用途之一是gson。 以下是使用gson的示例:

 String text = '[["item1","item2","item3"], ["some", "item"], ["far", "out", "string"]]'; GSON gson = new GSON(); ArrayList> list = gson.fromJson(text, new TypeToken>>() {}.getType()); 

这是gson网站: http : //code.google.com/p/google-gson/

您需要手动构建解析器。 这并不难,但需要时间。 在之前的评论中你说你想要一个ArrayList的ArrayList …嗯……好

只需通过char解析字符串char,并通过首先定义递归解析规则来识别每个标记。 递归后代解析器规则通常是图形化的,但我可以尝试使用ABNF

 LIST = NIL / LIST_ITEM *( ',' SP LIST_ITEM) LIST_ITEM = NIL / '[' STRING_ITEM *(, SP STRING ITEM) ']' STRING_ITEM = '"' ANYCHAR '"' SP = space ANYCHAR = you know, anything that is not double quotes NIL = '' 

另一种方法是使用正则表达式。 这里有几个样本。 首先捕获外部元素

 (\[[^\]]*\]) 

上面的正则表达式捕获从'[‘到第一个’]’的所有内容,但你需要修改它或从你的字符串中剪切括号(只需删除第一个和最后一个字符)

然后通过捕获内部元素

 (\"[^\"]\") 

如上所述简单