1

我有大量的日志行,我需要解析每一行(所以效率非常重要)。

每个日志行的格式为

cust_name time_start time_end (IP 或 URL)*

因此,ip 地址、时间、时间和一个可能为空的 ip 地址或 url 列表,以分号分隔。如果最后一个列表中只有 ip 或 url,则没有分隔符。如果超过 1 个,则用分号分隔。

我需要一种方法来解析这一行并将其读入数据结构。time_start 或 time_end 可以是系统时间或 GMT。cust_name 也可以有多个由空格分隔的字符串。

我可以通过逐个字符读取并编写自己的解析器来做到这一点。有一个更好的方法吗 ?

4

10 回答 10

7

也许 Boost RegExp lib 会帮助你。 http://www.boost.org/doc/libs/1_38_0/libs/regex/doc/html/index.html

于 2009-03-05T18:38:35.517 回答
5

在这类事情上,我已经使用Boost Tokenizer取得了成功。它可以帮助您将输入流分解为标记,并在标记之间使用自定义分隔符。

于 2009-03-05T18:45:16.373 回答
4

使用正则表达式(boost::regex对于 C++ 来说是一个很好的实现),您可以轻松地分隔字符串的不同部分 -cust_name, time_start ...并找到所有 urls\ips

如果需要,第二步是对该组进行更详细的解析。例如,您可以使用boost::datetime库解析日期(如果字符串格式不标准,则编写自定义解析器)。

于 2009-03-05T18:53:30.037 回答
3

为什么要在 C++ 中执行此操作?对于 perl 之类的东西来说,这听起来像是一项显而易见的工作。

于 2009-03-05T18:36:06.257 回答
2

考虑使用正则表达式库...

于 2009-03-05T18:35:25.477 回答
1

自定义输入需要自定义解析器。或者,祈祷有一个理想的世界,不存在错误。特别是,如果您想提高效率。发布一些代码可能会有所帮助。

于 2009-03-05T18:34:54.263 回答
1

对于这样一个简单的语法,您可以使用拆分,请查看http://www.boost.org/doc/libs/1_38_0/doc/html/string_algo/usage.html#id4002194

于 2009-03-05T18:47:31.720 回答
1

UPDATE彻底改变了答案!

我有大量的日志行,我需要解析每一行(所以效率非常重要)。

请注意,在这种情况下,C++ 在效率方面不会有太大帮助。不要误以为仅仅因为你在 C++ 中有一个快速解析代码,你的程序就会有高性能!

你在这里真正需要的效率不是解析代码的“机器码”级别的性能,而是整体算法级别的性能。

想想你想做什么。
你有一个巨大的文本文件,你想把每一行转换成一个数据结构,

无论您使用什么语言,在内存中存储巨大的数据结构都是非常低效的!

您需要做的是一次“获取”一行,将其转换为数据结构并进行处理,然后,只有在您完成数据结构后,您才去获取下一行并转换它到一个数据结构,处理它,然后重复。

如果你这样做,你已经解决了主要瓶颈。

对于解析文本行,您的数据格式似乎非常简单,请查看我前段时间提出的类似问题:C++ string parsing (python style)

在您的情况下,我想您可以使用字符串流,并使用>>运算符来读取行中的下一个“事物”。

请参阅此答案以获取示例代码。

或者,(我不想删除这部分!!)如果你可以用 python 编写它,它会简单得多。我不知道你的情况(看来你被 C++ 困住了),但仍然

查看此演示文稿以使用 python 生成器表达式有效地完成这些任务:http ://www.dabeaz.com/generators/Generators.pdf

值得一读。在幻灯片 31 中,他处理的内容似乎与您正在尝试做的事情非常相似。

它至少会给你一些灵感。
它还非常强烈地表明,性能不是通过特定的字符串解析代码获得的,而是通过整体算法获得的。

于 2009-03-05T18:59:03.393 回答
0

您可以尝试使用简单的 lex/yacc|flex/bison 词汇来解析这种输入。

于 2009-03-05T18:35:08.317 回答
0

您需要的解析器听起来很简单。看看这个。任何编译语言都应该能够以非常高的速度解析它。然后是您构建和保存的数据结构的问题。

于 2009-03-06T19:31:35.617 回答