首页 > 解决方案 > 这个正则表达式可以提高内存效率吗

问题描述

我得到一个 xml 作为普通的未格式化文本 blob。我必须进行一些替换,我使用正则表达式查找和替换。例如:

<MeasureValue><Text value="StartCalibration" /></MeasureValue>

必须转换为

<MeasureValue type="Text" value="StartCalibration"/>

我写的正则表达式是

<MeasureValue><((\w*)\s+value="(.*?)".*?)></MeasureValue>

替换部分是:

<MeasureValue type="$2" value="$3"/>

这里显示相同的链接。

问题是在一个有 370 次此类事件的文件中,我出现内存不足错误。我听说过所谓的贪婪正则表达式模式,想知道这是否会困扰我。如果这已经是内存高效的,那么我将保持原样并尝试增加服务器内存。我必须处理数以千计的此类文件。

编辑:这是来自 Elasticsearch 的 Logstash 脚本的一部分。根据文档,Elasticsearch 在内部使用 Apache Lucene 来解析正则表达式。不确定这是否有帮助。

标签: regexregex-groupregex-greedy

解决方案


根据经验,特异性与正则表达式的效率呈正相关。因此,了解您的数据并构建一些东西以通过手术匹配它。

您构建的正则表达式越具体,就像字面上写下模式(通常以一个怪异的正则表达式结束),由于它可以在您的数据中匹配的“可能性”越少,所需的资源就越少。

更准确地说,假设我们正在尝试匹配一个字符串

2014-08-26 app[web.1]: 50.0.134.125

方法如

(.*) (.*) (.*)

让它过于开放,容易与许多不同的模式和组合匹配,因此需要更多的时间来处理它的无限可能性。在这里查看https://regex101.com/r/GvmPOC/1

另一方面,您可以花更多的时间来构建更精细的表达式,例如:

^[0-9]{4}\-[0-9]{2}-[0-9]{2} app\[[a-zA-Z0-9.]+\]\: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$`

我同意,这很可怕,但更准确。它不会浪费您宝贵的资源寻找不必要的东西。在这里查看https://regex101.com/r/quz7fo/1

要记住的另一件事是:诸如*+执行扫描操作之类的运算符,这取决于字符串的大小,可能需要一些时间。此外,只要有可能,指定锚点^$还有助于脚本不要尝试在同一字符串中找到太多匹配项。


把它带到你的现实中......

如果我们必须使用正则表达式。

百万美元的问题是,我们怎样才能把你的正则表达式变成更精确的东西?

由于XML中的标签名称长度没有限制......没有办法让它完全具体:(

  • 我们可以尝试指定要匹配和避免的字符.\w。因此,将其替换为更喜欢的东西a-zA-Z是可取的。也利用否定类[^]将有助于缩小可能性的范围。

  • 避免*and?并尝试使用量词{}(虽然我不知道你的数据来做出这个决定)。正如我上面所说,XML 对此没有限制。

  • 我没有准确理解?代码中的功能,因此删除它是较少处理的事情。

结束了类似的东西

<(([a-zA-Z]+) value="([^"]*)"[^<>]*)>

不过变化不大。您可以尝试测量它,看看是否有任何改进。

但也许最好的方法是根本不使用正则表达式:(我不知道您正在使用的语言,但如果处理时间变得复杂,我建议您不要使用正则表达式并尝试一些替代方法。

如果使用xml 解析器的可能性很小,那将是更可取的。

https://softwareengineering.stackexchange.com/questions/113237/when-you-should-not-use-regular-expressions

很抱歉,如果它没有您预期的那么具有决定性,但研究它的领域同样非常开放。


推荐阅读