【问题标题】:Can this regex be made memory efficient这个正则表达式可以提高内存效率吗
【发布时间】:2020-04-29 02:24:46
【问题描述】:

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

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

必须转换为

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

我写的正则表达式是

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

替换零件是:

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

这里的link 显示相同。

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

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

【问题讨论】:

  • 你用什么语言实现这个正则表达式?
  • 这是来自 Elasticsearch 的 Logstash 脚本的一部分。根据文档,Elasticsearch 在内部使用 Apache Lucene 来解析正则表达式。不确定这是否有帮助。如果我找到它,我会继续寻找并添加更具体的信息。
  • 虽然可以改进模式(您可以通过使用负字符集而不是懒惰地重复使模式更快地失败),但我认为它不会导致灾难性的回溯或类似的事情,它不是非常效率低下。但是,在这种情况下,最好使用 XML 解析器而不是正则表达式
  • NotYetAgain,当被要求澄清时,正如@Certain 所做的那样,最好通过编辑问题来回应(并在适当的情况下添加标签,如此处),而不是在 cmets 中详细说明。问题应该是独立的,不应期望读者阅读所有 cmets 才能理解问题。
  • 对html/xml应用正则表达式会让一些人失去理智:stackoverflow.com/a/1732454/7915759

标签: regex regex-group regex-greedy


【解决方案1】:

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

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

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

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 的东西。使用否定类[^] 也有助于缩小可能性范围。

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

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

最终得到类似的东西

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

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

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

如果有一点可能使用 xml 解析器,那就更好了。

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

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

【讨论】:

  • 感谢您的回复。我将尝试提出一个更精确的目标正则表达式。最后会保留向它扔更多内存的选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
  • 2017-07-16
  • 2015-03-21
  • 2011-02-20
  • 1970-01-01
相关资源
最近更新 更多