从字符串中提取参数,包括带引号的区域,在Qt中 [英] Extract parameters from string, included quoted regions, in Qt
问题描述
我有一个Qt5 / C ++程序,它接收一个包含程序名称和可能的参数的QString。我需要把这个QString分成多个字符串。例如,字符串
I have a Qt5/C++ program which receives a QString containing a program name and possibly parameters. I need to split this QString into multiple strings. For example, the string
/tmp/myprog --param1 --param2=2 --param3="1 2 3" -p 4
应拆分为:
list[0]=/tmp/myprog
list[1]=--param1
list[2]=--param2=2
list[3]=--param3="1 2 3"
list[4]=-p 4
$ b b
我的第一个想法是在一个空格上使用split方法,但这会打破引用的param3。参数4在-p和4之间没有:或=。
My first thought was to use the "split" method on a space, but that would break param3 which is quoted. As well parameter 4 has no : or = between the -p and 4.
有一个简单的方法吗?我怀疑-p 4是不可能很容易分裂,因为没有办法知道是否下面的两个项目在一起。
Is there a simple way to do this? I suspect the -p 4 is impossible to split up easily since there is no way of knowing if the 2 items below together.
但是有一个拆分/ regex /其他方式拆分上面? (如果我们忽略-p 4是可能的?)
But is there a split/regex/other way to split the above? (If we ignore the -p 4 is it possible?)
更新:
同样的函数可以将字符串拆分为--param或-p?因此字符串
Could the same function split the string without the --param or -p? so a string of
abc "a a" "b b b" c
会成为
list[0]=abc
list[1]="a a"
list[2]="b b b"
list[3]=c
推荐答案
您的任务有两个方面:
-
将命令行拆分为参数。
Splitting of the command line into arguments. This needs to be implemented from scratch.
处理参数以提取参数及其值。自Qt 5.2以来,您可以使用 QCommandLineParser
来执行此操作。
Processing of the arguments to extract parameters and their values. Since Qt 5.2, you can use QCommandLineParser
to do that.
b
$ b
#include <QCoreApplication>
#include <QCommandLineParser>
#include <QDebug>
static QStringList splitCommandLine(const QString & cmdLine)
{
QStringList list;
QString arg;
bool escape = false;
enum { Idle, Arg, QuotedArg } state = Idle;
foreach (QChar const c, cmdLine) {
if (!escape && c == '\\') { escape = true; continue; }
switch (state) {
case Idle:
if (!escape && c == '"') state = QuotedArg;
else if (escape || !c.isSpace()) { arg += c; state = Arg; }
break;
case Arg:
if (!escape && c == '"') state = QuotedArg;
else if (escape || !c.isSpace()) arg += c;
else { list << arg; arg.clear(); state = Idle; }
break;
case QuotedArg:
if (!escape && c == '"') state = arg.isEmpty() ? Idle : Arg;
else arg += c;
break;
}
escape = false;
}
if (!arg.isEmpty()) list << arg;
return list;
}
int main(int argc, char * argv[])
{
QCoreApplication app(argc, argv);
QCommandLineParser parser;
parser.addHelpOption();
QCommandLineOption param1("param1");
QCommandLineOption param2("param2", "", "val2");
QCommandLineOption param3("param3", "", "val3");
QCommandLineOption param4("p", "", "val4");
parser.addOption(param1);
parser.addOption(param2);
parser.addOption(param3);
parser.addOption(param4);
if (true) {
// Parse a string
QString cmdLine("/tmp/myprog --param1 --param2=2\\ 2 --param3=\"1 2 3\" -p 4");
parser.parse(splitCommandLine(cmdLine));
} else {
// Parse a command line passed to this application
parser.process(app);
}
if (parser.isSet(param1)) qDebug() << "param1";
if (parser.isSet(param2)) qDebug() << "param2:" << parser.value(param2);
if (parser.isSet(param3)) {
QStringList values = parser.value(param3)
.split(' ', QString::SkipEmptyParts);
qDebug() << "param3:" << values;
}
if (parser.isSet(param4)) qDebug() << "param4:" << parser.value(param4);
return 0;
}
输出:
param1
param2: "2 2"
param3: ("1", "2", "3")
param4: "4"
QDebug
引用其输出的字符串。字符串本身不包含任何引号。
QDebug
quotes the strings it outputs. The strings themselves don't contain any quotes.
这篇关于从字符串中提取参数,包括带引号的区域,在Qt中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!