C++ 字符串标记化,按标记而非分隔符拆分

C++ 字符串标记化,按标记而非分隔符拆分,c++,string,tokenize,C++,String,Tokenize,我知道如何以传统的方式(即这里的答案)对字符串进行标记化,但是如何用它的标记(也包括它们)拆分字符串呢 例如,给定一个日期/时间图片,如yyyy\MMM\dd HH:mm:ss,我想将其拆分为具有以下内容的数组: "yyyy", "\", "MMM", "\", "dd", " " , "HH", ":", "mm", ":", "ss" 在本例中,“令牌”是yyyy、MMM、dd、HH、mm、ss。我不知道分隔符是什么,只知道代币是什么。但是,分隔符需要出现在最终结果中。令牌的完整列表为:

我知道如何以传统的方式(即这里的答案)对字符串进行标记化,但是如何用它的标记(也包括它们)拆分字符串呢

例如,给定一个日期/时间图片,如yyyy\MMM\dd HH:mm:ss,我想将其拆分为具有以下内容的数组:

"yyyy", "\", "MMM", "\", "dd", " " , "HH", ":", "mm", ":", "ss"
在本例中,“令牌”是yyyy、MMM、dd、HH、mm、ss。我不知道分隔符是什么,只知道代币是什么。但是,分隔符需要出现在最终结果中。令牌的完整列表为:

        "yyyy"  // – four-digit year, e.g. 1996
        "yy"    // – two-digit year, e.g. 96
        "MMMM"  // – month spelled out in full, e.g. April
        "MMM"   // – three-letter abbreviation for month, e.g. Apr
        "MM"    // – two-digit month, e.g. 04
        "M"     // – one-digit month for months below 10, e.g. 4
        "dd"    // – two-digit day, e.g. 02
        "d"     // – one-digit day for days below 10, e.g. 2
        "ss"    // - two digit second
        "s"     // - one-digit second for seconds below 10
        "mm"    // - two digit minute
        "m"     // - one-digit minute for minutes below 10
        "tt"    // - AM/PM designator
        "t"     // - first character of AM/PM designator
        "hh"    // - 12 hour two-digit for hours below 10
        "h"     // - 12 hour one-digit for hours below 10
        "HH"    // - 24 hour two-digit for hours below 10
        "H"     // - 24 hour one-digit for hours below 10
我注意到标准库std::string在解析和标记方面不是很强大,我不能使用boost。有没有一个紧凑的、惯用的解决方案?我不想为此而提出一个C风格的算法。性能不是一个考虑因素。

也许是你想要的,举个有用的例子

但是,它会吃掉分隔符。您可以通过比较基指针和结果字符串(按字符串长度向前移动)来解决该问题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <sstream>

int main() 
{
    char data[] = "yyyy\\MMM\\dd HH:mm:ss";
    std::vector<std::string> tokens;

    char* pch = strtok (data,"\\:");                                        // pch holds 'yyyy'
    while (pch != NULL)
    {
        tokens.push_back(pch);

        int delimeterIndex = static_cast<int>(pch - data + strlen(pch));    // delimeter index: 4, 8, ...
        std::stringstream ss;
        ss << delimeterIndex;
        tokens.push_back(ss.str());

        pch = strtok (NULL,"\\:");                                          // pch holds 'MMM', 'dd', ...
    }

    for (const auto& token : tokens)
    {
        std::cout << token << ", ";
    }
}

你的代币总是会是特殊字符,还是也会是字母?这些代币只是上面提到的那些。令牌之间的字符可能是一些日语字符(我必须使用wchar\t,因为我在Windows上,所以这也可能是一个问题)。对于任何给定的区域设置,日期/时间图片字符串基本上都是什么样子。我只知道它们的组件在图中用上面列出的标记定义。正则表达式是C++11的一部分:。除非性能不是绝对要求,否则使用正则表达式。正则表达式的问题是我必须花几个月的时间学习一种几乎无法理解的语法来解决这个稍微简单的问题。这是一种有趣的方法。
yyyy, 4, MMM, 8, dd HH, 14, mm, 17, ss, 20,