String text = '[["item1","item2","item3"], ["some", "item"], ["far", "out", "string"]]';
我想迭代每个单独的ArrayList。我不知道如何将该字符串转换为适当的ArrayList对象。
答案 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 = ''
另一种方法是使用正则表达式。这里有几个样本。首先通过
捕获外部元素(\[[^\]]*\])
上面的正则表达式捕获了从'['到第一个']'的所有内容,但是你需要修改它或从你的字符串中剪切括号(只需删除第一个和最后一个字符)
然后通过
捕捉内部元素(\"[^\"]\")
如上所述