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

时间:2010-10-10 01:01:55

标签: java

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

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

4 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:3)

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

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

"test"

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:-2)

您需要手动构建解析器。这并不难,但需要时间。 在之前的评论中,你说你想要一个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 = ''

另一种方法是使用正则表达式。这里有几个样本。首先通过

捕获外部元素
(\[[^\]]*\])

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

然后通过

捕捉内部元素
(\"[^\"]\")

如上所述