2017-07-25 474 views
3

我有一个QString的: “{X,C | 0×01}”,我想它,如下拆分令牌:如何拆分QString并保持Qt中的分隔符?

{ 
x 
, 
c 
| 
0x01 
} 

什么是做在Qt的最好方法是什么?

我试图使用QString::split(QRegExp("[\\{\\},|]")),但它不是保留结果中的分隔符。

+1

我不觉得在分离的任何逻辑,什么是分割它的特点呢? – eyllanesc

+0

我认为你最好的选择是迭代字符串并根据你的特定需求定义条件 –

+0

@eyllanesc我想用deliminator char分割它:'{','}',',','|' – ricky

回答

0

也许这个解决方案可以为您服务的任务:

int main(void) { 
    QString str { "{x, c | 0x01}" }; 
    QRegExp separators { "[\\{\\},|]" }; 

    QStringList list; 
    str.replace(" ", ""); 

    int mem = 0; 
    for(int i = 0; i<str.size(); ++i) { 
     if(i == str.indexOf(separators, i)) { 
      if(mem) list.append(str.mid(mem, i-mem)); // append str before separator 
      list.append(str.mid(i, 1));    // append separator 
      mem = i+1; 
     } 
    } 

    qDebug() << list; 

    return 0; 
} 

输出:("{", "x", ",", "c", "|", "0x01", "}")

可以消除if(mem)但随后使用list.pop_front();list.removeAll("");for周期之后,作为第一元素将是垃圾""

1


基本上,你迭代通过字符串,检查是否找到了定界符,然后将定界符添加到列表中。如果找不到分隔符,则将新的“词”添加到列表中,直到找到下一个分隔符,字符将被添加到该词中。请看:

//input string 
QString str = "{x, c | 0x01}"; 
QList<QString> out; 

//flag used to keep track of whether we're adding a mullti-char word, or just a deliminator 
bool insideWord = false; 

//remove whitespaces 
str = str.simplified(); 
str = str.replace(" ", ""); 

//iterate through string, check for delims, populate out list 
for (int i = 0; i < str.length(); i++) 
{ 
    QChar c = str.at(i); //get char at current index 
    if (c == '{' || c == '}' || c == ',' || c == '|') 
    { 
     //append deliminator 
     out.append(c); 
     insideWord = false; 
    } 
    else 
    { 
     //append new word to qlist... 
     if (!insideWord) 
     { 
      out.append(c); 
      insideWord = true; 
     } 
     //but if word already started 
     else 
     { 
      //add 'c' to the word in last index of the qlist 
      out.last().append(c); 
     } 
    } 
} 

//output as requested by OP 
qDebug() << "String is" << out; 
+0

感谢您的回答。实际上,我使用了一种非常类似于您的方法。但我想知道是否有更好的方法来避免调用str.insert()方法来提高性能? – ricky

+0

你说得对,使用str.insert()是非常愚蠢的。看看我的新代码,它使用StringBuilder连接到一个临时字符串。 – travisjayday

+0

我不明白,为什么你首先使用一个临时字符串,然后再分割它,如果你可以直接将这些标记添加到'QStringList'中(因为你已经有了这个标记!)! – xander

0

这可以在单个正则表达式中完成,但必须使用预见和后视。

在问题([\\{\\},|])指定的表达式将匹配的1字符长的字符串组成的任意字符{},|的。然后QString.split将删除该长度为1个字符的字符串。

需要的是使用前瞻:(?=[\\{\\},|])找到紧靠每个分隔符之前的零字符字符串,并且还可以在分隔符(?<=[\\{\\},|])之后立即找到零字符的字符串。

结合这些给出:

QString::split(QRegularExpression("(?=[\\{\\},|])|(?<=[\\{\\},|])")) 

这将给所需的输出:("{", "x", ",", "c", "|", "0x01", "}")