【问题标题】:Best method for tokenizing / extracting info from a string从字符串中标记/提取信息的最佳方法
【发布时间】:2011-01-20 21:09:57
【问题描述】:

我正在尝试将收到的日期时间转换为特定格式以插入 MySQL 数据库。该程序是用 C++ 编写的,以下解决方案有效,但我觉得它的效率非常低。

输入是:Mon Nov 08 17:41:23 +0000 2010
所需的输出格式为:YYYY-MM-DD HH:MM:SS
所以对于这个例子,输出将是:2010-11-08 17:41:23

我已经包含了代码的相关部分。

    //class variable
    std::map<std::string, std::string> monthMap;

void processor::initializeMonthMap(){
    monthMap["Jan"] = "01";
    monthMap["Feb"] = "02";
    monthMap["Mar"] = "03";
    monthMap["Apr"] = "04";
    monthMap["May"] = "05";
    monthMap["Jun"] = "06";
    monthMap["June"] = "06";
    monthMap["Jul"] = "07";
    monthMap["July"] = "07";
    monthMap["Aug"] = "08";
    monthMap["Sept"] = "09";
    monthMap["Sep"] = "09";
    monthMap["Oct"] = "10";
    monthMap["Nov"] = "11";
    monthMap["Dec"] = "12";
}

inline std::string processor::convertDate(std::string input) {
    //Format: Mon Nov 08 17:41:23 +0000 2010
    //To get to YYYY-MM-DD HH:MM:SS

    std::stringstream  newString(input);
    std::string temp1;
    std::string temp2;

    // Read Day in txt, discard
    newString >> temp1;

    //Read month, convert to number
    newString >> temp1;
    temp2 = "-" + monthMap[temp1] + "-";

    //Read Day in number
    newString >> temp1;
    temp2.append(temp1 + " ");

    //Read TimeStamp
    newString >> temp1;
    temp2.append(temp1);

    //Discard UTM adjustment
    newString >> temp1;

    //Read year
    newString >> temp1;

    //Add year to beginning of input
    temp1.append(temp2);

    return temp1;
}

【问题讨论】:

  • 您可以使用正则表达式(std::tr1 或 boost::regex)来获得干净的解决方案。如果您的格式是标准的,您也可以查看 Boost.Date_Time。
  • 你测量过编译器优化代码的运行吗?您的代码看起来非常简单。你可以挤出更多,但这值得吗?像您这样干净、易于理解且相当高效的代码非常值得。 (如果您刚刚将 tempXXX 重命名为合理的名称……;)
  • 总的来说,我同意@Peter。但是在这种情况下,使用日期/时间库,此代码基本上可以减少到两行:get_date_from_string(..., format) 后跟 get_string_from_date(..., other_format)。这样会更清楚更简洁。

标签: c++ string datetime tokenize


【解决方案1】:

您正在解析字符串,幸运的是您可以通过简单的附加来构建输出。我不认为这会变得更有效率。

但是,您似乎可以使用 seekg 将光标定位到一周中的某一天和 UTM 调整之后。

http://www.cplusplus.com/reference/iostream/istream/seekg/

【讨论】:

  • 提到的其他方法可能会减少代码,但不能解决 IMO 的效率问题。
  • 感谢您的信息。我确实对字符串流有疑问。你认为如果我使用 string.find() 而不是每次都构建一个 stringstream,我会做得更好吗?
  • 如果您知道各个部分的长度始终相同(它们看起来是相同的)。如果你想放弃 stringstream,我会使用 std::string::substr(start,count)。
【解决方案2】:

使用boost::date_time。您可以使用格式字符串以多种方式格式化输入和输出。

【讨论】:

    【解决方案3】:

    如果您使用的是 POSIX 系统(即不是 Windows),则可以使用 strptime: http://www.mkssoftware.com/docs/man3/strptime.3.asp

    这需要一个字符串并构建一个struct tm,您可以通过 strftime 以任何所需的格式输出它。

    有一些 Windows 实现,但默认情况下不可用。在此处查看更多信息:Convert a string to a date in C++

    【讨论】:

      猜你喜欢
      • 2012-03-18
      • 2012-02-09
      • 1970-01-01
      • 2011-11-21
      • 2010-09-10
      • 1970-01-01
      • 2015-01-25
      • 1970-01-01
      相关资源
      最近更新 更多