gpt4 book ai didi

c# - C# 中的 Regex.match 性能问题

转载 作者:太空狗 更新时间:2023-10-30 00:16:50 24 4
gpt4 key购买 nike

大家好我在 C# 中使用 Regex.match 来逐行调整文本文件。我发现当线条与模式不匹配时,它会花费更多时间(大约 2-4 秒)。但是匹配时花费的时间更少(少于 1 秒)。谁能告诉我如何提高性能?

这是我正在使用的正则表达式:

^.*?\t.*?\t(?<npk>\d+)\t(?<bol>\w+)\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t\s*(?<netValue>[\d\.,]+)\t.*?\t.*?\t(?<item>\d{6})\t(?<salesDoc>\d+)\t(?<acGiDate>[\d\.]{10})\t.*?\t.*?\t.*?\t.*?\t.*?\t(?<delivery>\d+)\t\s*(?<billQuantity>\d+)\t.*?\t(?<material>[\w\-]+)\tIV$

最佳答案

仅在正则表达式无法匹配时才会出现的性能问题通常是由于 catastrophic backtracking 引起的.当正则表达式允许许多可能的组合来匹配主题文本时,就会发生这种情况,所有这些组合都必须由正则表达式引擎尝试,直到它可能宣布失败。

在您的情况下,失败的原因很明显:

首先,您所做的实际上不应该使用正则表达式来完成,而应该使用 CSV 解析器(在您的情况下为 TSV 解析器)。

不过,如果您受困于正则表达式,您仍然需要进行一些更改。您的问题是分隔符 \t 也可以由点 (.) 匹配,因此除非整个字符串匹配,否则正则表达式引擎必须尝试大量排列,就像我上面概述的那样。

因此,向前迈出的一大步是将所有 .*? 更改为适用的 [^\t]*,并使用 {m,n} 运算符:

^(?:[^\t]*\t){2}(?<npk>\d+)\t(?<bol>\w+)(?:\t[^\t]*){9}\t\s*(?<netValue>[\d\.,]+)(?:\t[^\t]*){2}\t(?<item>\d{6})\t(?<salesDoc>\d+)\t(?<acGiDate>[\d\.]{10})(?:\t[^\t]*){5}\t(?<delivery>\d+)\t\s*(?<billQuantity>\d+)\t[^\t]*\t(?<material>[\w\-]+)\tIV$

希望我没有算错:)


仅供说明:

匹配这段文字

1   2   3   4   5   6   7   8   9   0

从上面的正则表达式中摘录

.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t.*?\t\s*(?<netValue>[\d\.,]+)

使用正则表达式引擎 39 个步骤。

不过,当您向它输入这段文字时:

1   2   3   4   5   6   7   8   9   X

它需要正则表达式引擎 4602 步来确定它无法匹配。

如果你使用

(?:[^\t]*\t){9}\s*(?<netValue>[\d\.,]+)

相反,引擎需要 30 个步骤才能成功匹配,而失败尝试只需 39 个步骤。

关于c# - C# 中的 Regex.match 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5039512/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com