1

我正在尝试在 1.12 GB 目录中的每个日志文件上运行 unix regEXP,然后将匹配的模式替换为''. 对一个 4 兆文件的测试运行大约需要 10 分钟,但工作正常。显然,某些东西会损害性能几个数量级。

更新:我注意到在 77 个匹配项的 5.6 MB 文件中搜索 ^(155[0-2]).*$ 需要大约 7 秒。添加 Negative Lookahead Assertion ?!,使 regExp 变为 ^(?!155[0-2]).*$ 导致它至少需要 5-10 分钟;当然,会有成千上万的比赛。

当有很多匹配时,否定的前瞻断言是否应该对性能极为不利?

4

2 回答 2

0

如果你能在一开始就摆脱.*它,那会有所帮助。在它之前可以是什么,只是空格?如果是这样,请尝试:

^(?!\s*155[0-2][0-9]{4}\s).*$

如果它真的可以是任何东西,请尝试使其不贪婪:

^(?!.*?155[0-2][0-9]{4}\s).*$

注意:在这两个示例中,我删除了第二个.*,因为第三个也会匹配相同的内容。

它有助于考虑正则表达式引擎实际上会做什么。

  1. 匹配^(行首)。没问题。
  2. 尝试匹配否定的前瞻断言
  3. 尽可能多地抓住.*。这意味着它抓住了整条线。
  4. 是下一个角色1吗?如果不是,则使.*匹配少一个字符并重复,直到它匹配 a 1

您可以看到这意味着对于每条不匹配的行,它将回溯到整行。现在,如果您只是\s*在开始时使用,那么只会抓取空格,而不是整行。如果它真的可以是任何东西,那么在匹配模式.*?的行上会更快,在不匹配的155行上会差不多。(在不匹配的行上,它将继续增长,.*直到它抓住整行。)

于 2010-03-30T19:23:40.900 回答
0

基本上:您使用的正则表达式实现是非线性的,只能以任何效率处理正则表达式语言的一个子集。请参阅我关于可以有效处理机器生成的正则表达式以获取更多背景的正则表达式实现的问题。

如果您可以选择其他实现,那么您很幸运;当我在寻找这些时,这些是稀缺的。两个合理的选项是RE2TRE,但它们都是库,而不是独立的可执行文件。

另一个选择是使用过去使用过的 unix 实用程序(grep?);grep 和许多其他 unix 实用程序一样,当然也有一个 windows 端口。

于 2010-10-19T09:20:17.797 回答