java: how to convert this string to ArrayList?

后端 未结 4 1604
说谎
说谎 2021-01-28 01:47
String text = \'[[\"item1\",\"item2\",\"item3\"], [\"some\", \"item\"], [\"far\", \"out\", \"string\"]]\';

I would like to iterate over each individual

4条回答
  •  时光取名叫无心
    2021-01-28 02:32

    Here's a simple parser, it should deal with all kinds of abusive nesting and will be robust to single and double quotes -- but it won't care if you mix them 'test" is treated equivalent to "test".

    edit: added comments, and now it deals with escaped quotes in strings. (and now improved string token handling even more)

    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();
        }
    
    }
    
    
    

    Just a couple of notes: this won't enforce your syntax to be correct, so if you do something goofy with the quotes, like I described, it might still get parsed as (un)expected. Also, I don't enforce commas at al, you don't even need a space between the quotes, so ["item1""item2"] is just as valid using this parser as ["item1", "item2"], but perhaps more oddly, this thing should also deal with ["item1"asdf"item2"] ignoring asdf.

    提交回复
    热议问题