regex - 这个正则表达式可以提高内存效率吗
问题描述
我得到一个 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 来解析正则表达式。不确定这是否有帮助。
解决方案
根据经验,特异性与正则表达式的效率呈正相关。因此,了解您的数据并构建一些东西以通过手术匹配它。
您构建的正则表达式越具体,就像字面上写下模式(通常以一个怪异的正则表达式结束),由于它可以在您的数据中匹配的“可能性”越少,所需的资源就越少。
更准确地说,假设我们正在尝试匹配一个字符串
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 解析器的可能性很小,那将是更可取的。
很抱歉,如果它没有您预期的那么具有决定性,但研究它的领域同样非常开放。
推荐阅读
- java - 应用关闭时 Android Studio 和 Firebase 数据库中的通知
- javascript - 我的 AJAX 工作正常,我想知道为什么
- c - 在定义中使用静态关键字与在 C 中声明
- javascript - React,MongoDB,Mongoose:如何格式化我的日期以使其可读?
- python - 创建满足条件的变量列表,而无需手动键入它们
- c# - 在特定范围内查找时间
- aws-lambda - 使用 FAAS 执行“setTimeout”或“setInterval”的最佳方法是什么?
- javascript - 如何将新项目添加到 json 并插入到 mongodb
- windows - 为什么选择奇怪地返回错误级别?
- python - 为什么我无法根据另一列中的值替换数据框一列中的这些 NA 值?[Python]