【问题标题】:How to parse for lines with specific format in a file如何解析文件中具有特定格式的行
【发布时间】:2015-04-13 14:04:49
【问题描述】:

我最近尝试自己解析字幕文件来修改时间。格式很简单,有效的一行是这样的:

<arbitrary lines might include comments, blanks, random stuff>
<consecutively numbered ID here>
01:23:45,678 --> 01:23:47,910
<arbitrary lines might include comments, blanks, random stuff>

如何在 C++ 中以优雅的方式做到这一点。我只提出了非常丑陋的解决方案。例如,要逐行读取文件,在每个文件中搜索“-->”,然后使用 find(':')、find(',') 和 substr()

我觉得一定有更好的方法,例如以某种方式用令牌分割。如果我仍然可以解析以下行,那将是理想的:

01 : 23    :45,678   -->  01:23:   45, 910  

正确。最终结果应该是变量中的每个部分(hh、mm、ss、ms)。我不一定要求完整的实施。一个大致的想法和对适当实用函数的引用就足够了。

【问题讨论】:

  • 除了将大量数据读入缓冲区并解析缓冲区之外;逐行读取到std::string 是解析文本文件的常用和首选方法。
  • 您的文件格式未定义,或者您没有(提供)足够的信息
  • 一些灵感here.
  • 好的,似乎没有简单的答案。我希望这可以在几个实用 IO 函数的帮助下完成。我喜欢状态机方法,因为我们在大学做的事情非常相似。将每一行读入字符串的问题在于,我无法像使用 ifstream 那样继续使用 getline 和自定义分隔符解析它。那么没有什么比 find、substr 和 trim 序列更好的了?我的文件格式@DieterLücking 到底有什么未定义的?

标签: c++ parsing text token


【解决方案1】:

您只需使用std::regex 即可。您定义要提取的标记,正则表达式将为您完成。当然你可以修改输入字符串。它仍然可以工作。您可以继续使用向量中的数据。比较简单。

查看一些骨架代码示例:

#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <regex>

// Our test data (raw string). So, containing also \" and so on
std::string testData(R"#(01 : 23    :45,678   -->  01:23:   45, 910  ?")#");

std::regex re(R"#((\b\d+\b))#");

int main(void)
{
    // Define the variable id as vector of string and use the range constructor to read the test data and tokenize it
    std::vector<std::string> id{ std::sregex_token_iterator(testData.begin(), testData.end(), re, 1), std::sregex_token_iterator() };

    // For debug output. Print complete vector to std::cout
    std::copy(id.begin(), id.end(), std::ostream_iterator<std::string>(std::cout, " "));

    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多