Java字符转义

时间:2015-06-09 13:30:14

标签: java escaping

在编程的过程中,我发现了java String的奇怪行为。我试图用字符解析一个字符串作为命令:

以下是调试期间变量的屏幕截图。

enter image description here

这是我阅读命令的代码:

public List<String> readCommand(Sender sender, String command) {
    boolean isInQuote = false;
    List<String> splits = new ArrayList();
    String current = "";
    char[] arr = command.toCharArray();
    for (int i = 0; i < command.toCharArray().length; i++) {
        char c = arr[i];
        if (c == '"') {
        isInQuote = !isInQuote;

        if (!isInQuote) {
            splits.add(current);
            current = "";
        }
        }

        if (isInQuote) {
        current += c;
        } else {
        if (c == ' ' || i == arr.length - 1) {
            if (i == arr.length - 1) {
            current += c;
            }
            splits.add(current);
            current = "";
        } else {
            current += c;
        }
        }
    }

    return splits;
    }

正如测试中预期的那样;该字符串应解析为:

  1. “这个”
  2. “是一个测试”
  3. “现在”
  4. 而是将其解析为:

    1. “这个”
    2. “\”是一个测试“
    3. “\”“
    4. “现在”
    5. 为什么逃脱的报价不起作用,我做错了什么?

      P.S。:我会尝试研究这个问题,但我不知道怎么称呼它。使用引号解析参数...?

      更新:在你的帮助之后,我发现了另一个我修复过的错误。代码现在完全正常工作。现在剩下的就是重拍它:)。 “不工作真让我迷惑。http://pastebin.com/AdBUqJvH

3 个答案:

答案 0 :(得分:1)

这是您的任务的解决方案。

public static void main(String[] args) {
    List<String> splits = readCommand("this \"is a\" test\" now");
    for(String str : splits) {
            System.out.println("_"+str+"_");
    }
}

public static List<String> readCommand(String command) {
    List<String> list = Arrays.asList(command.split("\""));
    List<String> list2 = new ArrayList<>();
    for(String str : list) {
        str = checkFirst(str);
        str = checkLast(str);
        list2.add(str);
    }
    return list2;
}

private static String checkFirst(String str) {
    if (str.charAt(0) == ' ') {
        str = checkFirst(str.substring(1));
    }
    return str;
}

private static String checkLast(String str) {
    if (str.charAt(str.length() - 1) == ' ') {
        str = checkLast(str.substring(0, str.length() - 1));
    }
    return str;
}

答案 1 :(得分:1)

您的代码适用于我。除了输出是

这&#34;是一个测试&#34; &#34;现在

而不是

这&#34;是一个测试&#34;现在

我做了一个小改动

你说你输入的内容并不总是包含&#39;&#34;&#39;,但你很难用&#39;&#34;&#34;&# 39;所以[Igor Sadovnikov]的答案可能更好吗?

    public static void main(String[] args) {
        String s = "this \"is a test\" now";
        List<String> commands = readCommand(null, s);
        for (String command : commands) {
            System.out.print(command + " ");
        }
    }

    private static List<String> readCommand(Object sender, String command) {
        boolean isInQuote = false;
        List<String> splits = new ArrayList<String>();
        String current = "";
        char[] arr = command.toCharArray();
        for (int i = 0; i < command.toCharArray().length; i++) {
            char c = arr[i];
            if (c == '"') {
                isInQuote = !isInQuote;

                if (!isInQuote) {
                    //CHANGE HERE  ... added + c
                    splits.add(current + c);
                    current = "";
                }
            }

            if (isInQuote) {
                current += c;
            } else {
                if (c == ' ' || i == arr.length - 1) {
                    if (i == arr.length - 1) {
                        current += c;
                    }
                    splits.add(current);
                    current = "";
                } 
                // --- CHANGE HERE
                else if (c != '"') {
                    current += c;
                }
            }
        }

        return splits;
    }

答案 2 :(得分:1)

首先,让我们通过以下方式简化您当前的尝试:

public static void main(String[] args) throws Exception {
    String data = "this \"is a test\" now \"hello\" goodbye";

    List<String> splits = new ArrayList();
    String current = "";
    boolean inQuote = false;        
    for (int i = 0; i < data.length(); i++) {
        if (data.charAt(i) == ' ' && !inQuote) {
            // Add your current split word and move on to the next character
            splits.add(current);
            current = "";
            continue; 
        } else if (data.charAt(i) == '\"') {
            // Flip the flag whenever you run across a quotation mark
            inQuote = !inQuote;
        }

        // Add current character to string, spaces never get added
        current += data.charAt(i);
    }
    // Add remaining split data from hitting the end of data
    if (!current.isEmpty()) {
        splits.add(current);
    }

    // Display results
    for (String split : splits) {
        System.out.println(split);
    }
}

结果:

this
"is a test"
now
"hello"
goodbye

正则表达式

然后,您可以使用Regex缩短代码并使用以下内容(结果相同):

public static void main(String[] args) throws Exception {
    String data = "this \"is a test\" now \"hello\" goodbye";

    Matcher matcher = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'").matcher(data);
    while (matcher.find()) {
        System.out.println(matcher.group());
    }
}