简体   繁体   中英

Command parsing with quotes within quotes

I have been trying to parse a command with regular expression in Java for a while but no success. The main issue I am having is that the delimiter is space and then I want to treat everything that is within a double quotes as an argument but what if one of these arg contains quotes within quotes. Here is the command and few examples:

my_command "regex or text" <"regex or text"|NA> <"text or regex"|NA> integer integer 

Example1: my_command "Simple case" NA NA 2 3 

Example2: my_command "This is it!" "[\",;']" "Really?" 3 5

Example3: my_command "Not so fast" NA "Another regex int the mix [\"a-zA-Z123]" 1 1

Basically parseCommand(String str) will take any of the above examples and return a List with the following values:

Example1: list[0] = "Simple Case", list[1] = NA, list[2] = NA, list[3] = "2", list[4] = "3"

Example2: list[0] = "This is it!", list[1] = "[\",;']", list[2] = NA, list[3] = "3", list[4] = "5"
Example3: list[0] = "Not so fast", list[1] = NA, list[2] = "Another regex int the mix [\"a-zA-Z123]" , list[3] = "1", list[4] = "1"

Thank you for your help in advance.

Trying to do this with a regex is a mistake - you are not parsing a regular expression .

Start with something like this - you will fail with a regex:

public void test() {
    System.out.println(parse("\"This is it!\" \"[\\\",;']\" \"Really?\" 3 5"));
}

List<String> parse(String s) {
    List<String> parsed = new ArrayList<String>();
    boolean inQuotes = false;
    boolean escape = false;
    int from = 0;
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        switch (ch) {
            case ' ':
                if (!inQuotes && !escape) {
                    parsed.add(s.substring(from, i));
                    from = i + 1;
                }
                break;
            case '\"':
                if (!escape) {
                    inQuotes = !inQuotes;
                }
                escape = false;
                break;
            case '\\':
                escape = !escape;
                break;
            default:
                escape = false;
                break;
        }
    }

    if (from < s.length()) {
        parsed.add(s.substring(from, s.length()));
    }
    return parsed;
}

Added

With the specific string in question, here is my interpretation:

String str = "my_command \"Something [\"abc']\" \"text\" NA 1 1";
//                         ............        ..       .......
//                        ^            ^      ^  ^     ^

I have used a ^ to indicate a quote and used . for all characters therefore in quotes. Thus no further splits after the first quote as there are no unquoted spaces after that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM