我需要解析流中看起来像这样的行:command "string1" "string2"
字符串可以包含空格和转义双引号。我需要拆分它,以便我得到命令,string1和string2作为数组元素。我认为split()与正则表达式匹配"
而不是\"
(.split("(?<!\\\\)\"")
)可以完成这项工作,但我听说这不是一个好主意。
在Java中有没有更好的方法呢?
答案 0 :(得分:3)
这样的事情可以解决这个问题,假设你想在适用的时候删除外部双引号(如果你不这样做,只需要改变第一个捕获组也包括引号):
public class Demo {
private static final Pattern WORD =
Pattern.compile("\"((?:[^\\\\\"]|\\\\.)*)\"|([^\\s\"]+)");
public static void main(String[] args) {
String cmd =
"command " +
"\"string with blanks\" " +
"\"anotherStringBetweenQuotes\" " +
"\"a string with \\\"escaped\\\" quotes\" " +
"stringWithoutBlanks";
Matcher matcher = WORD.matcher(cmd);
while (matcher.find()) {
String capturedGroup = matcher.group(1) != null ? matcher.group(1) : matcher.group(2);
System.out.println("Matched: " + capturedGroup);
}
}
}
输出:
Matched: command
Matched: string with blanks
Matched: anotherStringBetweenQuotes
Matched: a string with \"escaped\" quotes
Matched: stringWithoutBlanks
正则表达式有点复杂,所以值得一点解释:
[^\\\\\"]
匹配除反斜杠或双引号之外的所有内容\\\\.
匹配反斜杠后跟任何字符(包括双引号),即转义字符(?:[^\\\\\"]|\\\\.)*
匹配任何已转义或未转义的字符序列,但未捕获该组(因为(?:)
)"\"((?:[^\\\\\"]|\\\\.)*)\"
匹配包含在双引号中的任何此类序列并捕获引号内部([^\\s\"]+)
匹配任何非空的非空字符序列,并将其捕获到一个组中