编辑 3
当我被正则表达式卡住时,我采用了 good'ol 自定义解析方法。结果并没有那么糟糕,因为文件内容可以非常整齐地标记化,并且可以使用非常简单的状态机在循环中解析标记。那些想要检查的人,在 Stackoverflow here中的另一个问题中,有一段代码使用 range-for、ifstream 迭代器和自定义流标记器执行此操作。这些技术大大降低了执行自定义解析器的复杂性。
我想在第一部分中以两个为一组的捕获组对文件内容进行标记,然后逐行标记。我喜欢一个半功能性的解决方案,但我想学习如何让它变得更好。也就是说,没有“额外处理”来弥补我对捕获组的知识不足。接下来是一些初步的,最后是一个更准确的问题(行
const std::regex expression("([^:]+?)(^:|$)");
...是我想结合处理结果来询问的问题)。
基本上是这样定义的文件:
definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
definition_literal : value_literal
HOW TO INTERPRET THE FOLLOWING SECTION OF ROWS
[DATA ROW 1]
[DATA ROW 2]
...
[DATA ROW n]
其中每个数据行由一定数量的整数或浮点数组成,由空格分隔。每行具有与其他行一样多的数字(例如,每行可以有四个整数)。因此,“解释部分”基本上以纯文本形式在一行中讲述了这种格式。
我有一个几乎可以正常工作的解决方案,可以读取这样的文件:
int main()
{
std::ifstream file("xyz", std::ios_base::in);
if(file.good())
{
std::stringstream file_memory_buffer;
file_memory_buffer << file.rdbuf();
std::string str = file_memory_buffer.str();
file.close();
const std::regex expression("([^:]+?)(^:|$)");
std::smatch result;
const std::sregex_token_iterator end;
for(std::sregex_token_iterator i(str.begin(), str.end(), expression); i != end; ++i)
{
std::cout << (*i) << std::endl;
}
}
return EXIT_SUCCESS;
}
使用定义的正则表达式expression
,它现在打印<value>
定义文件的部分,然后是解释部分,然后是数据行。如果我将正则表达式更改为
"([^:]+?)(:|$)"
...它打印所有标记为一组的行,几乎就像我想要的那样,但是如何将第一部分标记为两组,其余部分逐行标记?
任何指针、代码、解释都非常受欢迎。谢谢。
编辑:
正如Tom Kerr已经指出的那样,但还有一些额外的点,这也是一次排练,或者如果你愿意,也可以编码 kata,不要编写自定义解析器,而是看看我是否可以——或者我们可以:-)——完成这与正则表达式。我知道正则表达式在这里不是最有效的事情,但这没关系。
我希望拥有的是类似于标题信息元组的列表(大小为 2 的元组),然后是 INTERPRET 行(大小为 1 的元组),我可以用它来选择一个函数来处理数据行(大小为 1 的元组)。
是的,“如何解释”行包含在一组定义明确的字符串中,我可以从头开始逐行读取,沿途拆分字符串,直到遇到其中一个解释行。我知道,这个正则表达式解决方案不是最有效的方法,但更像是编写 kata 代码让自己编写除客户解析器之外的其他东西(我上次用 C++ 编写已经有一段时间了,所以这也是在排练)。
编辑 2
我已经设法通过更改迭代器类型来访问元组(在这个问题的上下文中),就像这样
const std::sregex_iterator end;
for(std::sregex_iterator i(str.begin(), str.end(), expression); i != end; ++i)
{
std::cout << "0: " << (*i)[0] << std::endl;
std::cout << "1: " << (*i)[1] << std::endl;
std::cout << "2: " << (*i)[2] << std::endl;
std::cout << "***" << std::endl;
}
尽管这与我想要的还有很长的路要走,但我尝试使用的正则表达式有问题。无论如何,这个新发现,另一种迭代器,也有帮助。