我一直试图用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"
提前感谢您的帮助。
答案 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";
// ............ .. .......
// ^ ^ ^ ^ ^
我使用^
来表示引用,并因此在引号中使用.
表示所有字符。因此,在第一次引用之后没有进一步的分裂,因为之后没有没有引用的空格。