Вопрос-ответ

Regex for splitting a string using space when not surrounded by single or double quotes

Регулярное выражение для разделения строки с использованием пробела, если она не заключена в одинарные или двойные кавычки

Я новичок в регулярных выражениях и был бы признателен за вашу помощь. Я пытаюсь составить выражение, которое разделит строку примера, используя все пробелы, которые не заключены в одинарные или двойные кавычки. Моя последняя попытка выглядит так: (?!") и не совсем работает. Это разделение на пробел перед кавычкой.

Пример ввода:

This is a string that "will be" highlighted when your 'regular expression' matches something.

Желаемый результат:

This
is
a
string
that
will be
highlighted
when
your
regular expression
matches
something.

Обратите внимание, что "will be" и 'regular expression' между словами сохраняется пробел.

Переведено автоматически
Ответ 1

Я не понимаю, почему все остальные предлагают такие сложные регулярные выражения или такой длинный код. По сути, вы хотите извлечь из вашей строки два вида объектов: последовательности символов, которые не являются пробелами или кавычками, и последовательности символов, которые начинаются и заканчиваются кавычкой, без кавычек между ними, для двух видов кавычек. Вы можете легко сопоставить эти параметры с помощью этого регулярного выражения:

[^\s"']+|"([^"]*)"|'([^']*)'

Я добавил группы захвата, потому что вы не хотите, чтобы кавычки были в списке.

Этот Java-код создает список, добавляя группу захвата, если она совпадает, чтобы исключить кавычки, и добавляя полное совпадение регулярных выражений, если группа захвата не совпадает (было найдено слово без кавычек).

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"([^\"]*)\"|'([^']*)'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
if (regexMatcher.group(1) != null) {
// Add double-quoted string without the quotes
matchList.add(regexMatcher.group(1));
} else if (regexMatcher.group(2) != null) {
// Add single-quoted string without the quotes
matchList.add(regexMatcher.group(2));
} else {
// Add unquoted word
matchList.add(regexMatcher.group());
}
}

Если вы не возражаете против наличия кавычек в возвращаемом списке, вы можете использовать гораздо более простой код:

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s\"']+|\"[^\"]*\"|'[^']*'");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
matchList.add(regexMatcher.group());
}
Ответ 2

В StackOverflow есть несколько вопросов, которые охватывают этот же вопрос в различных контекстах с использованием регулярных выражений. Например:

ОБНОВЛЕНИЕ: Пример регулярного выражения для обработки строк, заключенных в одинарные и двойные кавычки. Ссылка: Как я могу разделить строку, кроме как внутри кавычек?

m/('.*?'|".*?"|\S+)/g 

Протестировал это с помощью быстрого фрагмента Perl, и результат был таким, как показано ниже. Также работает с пустыми строками или строками только с пробелами, если они заключены в кавычки (не уверен, желательно это или нет).

This
is
a
string
that
"will be"
highlighted
when
your
'regular expression'
matches
something.

Обратите внимание, что это включает сами символы кавычек в сопоставляемые значения, хотя вы можете удалить это с помощью замены строки или изменить регулярное выражение, чтобы не включать их. Я пока оставлю это в качестве упражнения для читателя или другого плаката, поскольку 2 часа ночи - это слишком поздно, чтобы больше возиться с регулярными выражениями ;)

Ответ 3

Если вы хотите разрешить экранированные кавычки внутри строки, вы можете использовать что-то вроде этого:

(?:(['"])(.*?)(?<!\\)(?>\\\\)*\1|([^\s]+))

Строки, заключенные в кавычки, будут группой 2, отдельные слова без кавычек - группой 3.

Вы можете попробовать это для различных строк здесь: http://www.fileformat.info/tool/regex.htm или http://gskinner.com/RegExr /

Ответ 4

Регулярное выражение от Яна Гойвертса - лучшее решение, которое я нашел на данный момент, но создает также пустые (null) совпадения, которые он исключает в своей программе. Эти пустые совпадения также отображаются в тестерах регулярных выражений (например, rubular.com). Если вы измените порядок поиска (сначала ищите части, заключенные в кавычки, а затем разделенные пробелом слова), то вы могли бы сделать это сразу с помощью:

("[^"]*"|'[^']*'|[\S]+)+
java regex