使用引号引用命令解析

时间:2014-09-17 15:36:56

标签: java regex

我一直试图用Java中的正则表达式解析命令一段时间但没有成功。我遇到的主要问题是分隔符是空格,然后我想将双引号内的所有内容视为参数,但如果其中一个arg包含引号内的引号,该怎么办呢。这是命令和几个例子:

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

基本上parseCommand(String str)将采用上述任何示例并返回具有以下值的List:

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"

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

尝试使用正则表达式执行此操作是一个错误 - 您没有解析regular expression

从这样的事情开始 - 你将fail使用正则表达式:

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

<强>加

有问题的具体字符串,这是我的解释:

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

我使用^来表示引用,并因此在引号中使用.表示所有字符。因此,在第一次引用之后没有进一步的分裂,因为之后没有没有引用的空格。