Задача:
Имеется строка со словами, разделенными пробелами. Но некоторые группы слов могут быть заключены в одинарные или двойные кавычки, и должны считаться одним словом. Как разделить такую строку на элементы?
Другими словами, есть, к примеру строка, содержащая Bash-команду, в которой несколько аргументов. Но некоторые аргументы заключены в кавычки, и содержат внутри себя пробелы. Естественно, такие аргументы с пробелами должны являться одним элементом. Вопрос в том, как получить QStringList, в котором будут находиться все аргументы Bash-команды, где каждый аргумент - это валидный элемент, полученный с учетом наличия кавычек.
Решение:
Ниже приведен проверенный Qt/C++ код, который разбивает строку с учетом наличия в ней одинарных или двойных кавычек.
#include <QRegularExpression>
#include <QStringList>
#include <QDebug>
#include "main.h"
int main() {
QString str = R"(one two "three four" 'five six')";
// Регулярное выражение для разделения строки
QRegularExpression regex( R"(\"([^\"]*)\"|'([^']*)'|(\S+))" );
QStringList result;
QRegularExpressionMatchIterator i = regex.globalMatch(str);
// Перебираем совпадения
while (i.hasNext()) {
QRegularExpressionMatch match = i.next();
if (match.hasMatch()) {
// Берем первое непустое совпадение (группы с кавычками или слова без кавычек)
result << ( match.captured(1).isEmpty() ?
(match.captured(2).isEmpty() ? match.captured(3) : match.captured(2))
: match.captured(1) );
}
}
// Выводим результат
qDebug() << result; // Output: ("one", "two", "three four", "five six")
return 0;
}
В данном коде используются "сырые" строки, обозначаемые как R"(...)". Этот формат строк появился в C++11, поэтому надо контролировать опции сборки, чтобы поддержка C++11 была включена. Да, символы круглых скобок "(" и ")" - это часть обозначения "сырой" строки, и они в конечную строку не попадают.