在Qt中从字符串(包括引用的区域)中提取参数

TSG*_*TSG 2 c++ regex qt split

我有一个Qt5/C++程序,它接收一个包含程序名称和可能的参数的QString.我需要将此QString拆分为多个字符串.例如,字符串

/tmp/myprog --param1 --param2=2 --param3="1 2 3" -p 4
Run Code Online (Sandbox Code Playgroud)

应分为:

list[0]=/tmp/myprog
list[1]=--param1
list[2]=--param2=2
list[3]=--param3="1 2 3"
list[4]=-p 4
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是在空间上使用"拆分"方法,但这会打破引用的param3.同样,参数4在-p和4之间没有:或=.

有一个简单的方法吗?我怀疑-p 4是不可能轻易拆分的,因为无法知道下面的两个项目是否在一起.

但是有分裂/正则表达/其他方式分裂上述?(如果我们忽略-p 4有可能吗?)


更新:

相同的函数可以在没有--param或-p的情况下拆分字符串吗?所以一串

abc "a a" "b b b"  c
Run Code Online (Sandbox Code Playgroud)

会成为

list[0]=abc
list[1]="a a"
list[2]="b b b"
list[3]=c
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 7

您的任务有两个方面:

  1. 将命令行拆分为参数.这需要从头开始实施.

  2. 处理提取参数及其值的参数.从Qt 5.2开始,您可以使用QCommandLineParser它.

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

param1
param2: "2 2"
param3: ("1", "2", "3")
param4: "4"
Run Code Online (Sandbox Code Playgroud)

QDebug引用它输出的字符串.字符串本身不包含任何引号.