Первое, что вам нужно сделать, это перестать думать о работе в терминах split()
. split()
предназначен для разбиения простых строк, таких как this/that/the other
, где /
всегда является разделителем. Но вы пытаетесь разделить пробел, , если пробел не находится в кавычках, за исключением , если кавычки экранированы обратным слэшем (и если обратный слэш экранирует кавычки, возможно, они избегают других вещей, как и другие обратные слеши).
Со всеми этими исключениями просто невозможно создать регулярное выражение для сопоставления со всеми возможными разделителями, даже с такими причудливыми уловками, как обходные пути, условные выражения, неохотные и притяжательные квантификаторы. То, что вы хотите сделать, это сопоставить токены , а не разделители.
В следующем коде токен, заключенный в двойные или одинарные кавычки, может содержать пробел, а также символ кавычки, если ему предшествует обратный слеш. Все, кроме заключающих в кавычки, записывается в группу № 1 (для двойных кавычек) или группу № 2 (в одинарных кавычках). Любой символ может быть экранирован обратной косой чертой, даже в токенах без кавычек; «убегающие» обратные слеши удаляются в отдельном шаге.
public static void test()
{
String str = "\"Hello\\\" World\" 'Hello Universe' Hi";
List<String> commands = parseCommands(str);
for (String s : commands)
{
System.out.println(s);
}
}
public static List<String> parseCommands(String s)
{
String rgx = "\"((?:[^\"\\\\]++|\\\\.)*+)\"" // double-quoted
+ "|'((?:[^'\\\\]++|\\\\.)*+)'" // single-quoted
+ "|\\S+"; // not quoted
Pattern p = Pattern.compile(rgx);
Matcher m = p.matcher(s);
List<String> commands = new ArrayList<String>();
while (m.find())
{
String cmd = m.start(1) != -1 ? m.group(1) // strip double-quotes
: m.start(2) != -1 ? m.group(2) // strip single-quotes
: m.group();
cmd = cmd.replaceAll("\\\\(.)", "$1"); // remove escape characters
commands.add(cmd);
}
return commands;
}
выход:
Hello" World
Hello Universe
Hi
Это примерно так же просто, как и для решения на основе регулярных выражений - и на самом деле оно не имеет дело с некорректным вводом, таким как несбалансированные кавычки. Если вы не владеете регулярными выражениями, возможно, вам лучше использовать решение, написанное вручную, или, что еще лучше, выделенную библиотеку интерпретатора командной строки (CLI).