2016-04-25 204 views
1

我看到如何以传统方式标记字符串(即这里的答案为How do I tokenize a string in C++?),但我怎样才能通过它的标记分割字符串,还包括它们?字符串标记化,按标记分隔而不是分隔符

例如,给定的日期/时间的图片,例如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是不是在解析和tokenising非常强,我不能使用的推动作用。有没有一种紧凑,惯用的解决方案?我讨厌为此做出一个C风格的算法。性能不是考虑因素。

+0

是你的令牌总是将是特殊字符,或者也可以是字母吗? – WearyWanderer

+0

令牌只有上述那些。令牌之间的字符可能是一些日文字符(我必须使用wchar_t,因为我在Windows上,所以这可能也是一个问题)。基本上无论日期/时间图片字符串看起来像任何给定的语言环境。我所知道的所有关于它们的部件都是在图片中用上面列出的标记定义的。 – Robinson

+1

正则表达式是C++ 11的一部分:http://www.cplusplus.com/reference/regex/。除非性能不是绝对要求,否则使用正则表达式。 – Dummy00001

回答

1

也许http://www.cplusplus.com/reference/cstring/strtok/是你正在寻找的,一个有用的例子。

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

#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 << ", "; 
    } 
} 

这给出了输出:

yyyy, 4, MMM, 8, dd HH, 14, mm, 17, ss, 20, 
+0

这是一个有趣的方法。 – Robinson