gpt4 book ai didi

c# - 大字符串正则表达式替换 C# 中的性能

转载 作者:太空狗 更新时间:2023-10-30 01:34:51 25 4
gpt4 key购买 nike

我在 C# 中遇到正则表达式性能问题。

我需要替换一个非常大的字符串(270k 个字符,不要问为什么..)。正则表达式匹配了大约 3k 次。

private static Regex emptyCSSRulesetRegex = new Regex(@"[^\};\{]+\{\s*\}", RegexOptions.Compiled | RegexOptions.Singleline);

public string ReplaceEmptyCSSRulesets(string css) {
return emptyCSSRulesetRegex.Replace(css, string.Empty);
}

我传递给方法的字符串看起来像这样:

.selector-with-statements{border:none;}.selector-without-statements{}.etc{}

目前替换过程在 C# 中占用 1500ms,但当我在 Javascript 中完全相同时,它只需要 100ms

我用来计时的 Javascript 代码:

console.time('reg replace');
myLargeString.replace(/[^\};\{]+\{\s*\}/g,'');
console.timeEnd('reg replace');

我还尝试通过以相反顺序循环匹配并替换 StringBuilder 中的字符串来进行替换。那没有帮助。

在这种情况下,我对 C# 和 Javascript 之间的性能差异感到惊讶,我认为我做错了什么,但我想不出任何东西。

最佳答案

我真的无法解释 Javascript 和 C# 之间的时间差异(*)。但是您可以尝试提高模式的性能(产生大量回溯):

private static Regex emptyCSSRulesetRegex = new Regex(@"(?<keep>[^};{]+)(?:{\s*}(?<keep>))?", RegexOptions.Compiled);

public string ReplaceEmptyCSSRulesets(string css) {
return emptyCSSRulesetRegex.Replace(css, @"${keep}");
}

原始模式的一个问题是,当大括号不为空(或未填充空格)时,正则表达式引擎将继续测试左大括号之前的每个位置(结果始终相同)。示例:使用字符串 abcd{1234} 您的模式将从 a 开始测试,然后是 b ...

我建议的模式将消耗 abcd,即使它后面没有空大括号,所以 bcd 的位置没有测试。

abcd 在名为 keep 的组中被捕获,但是当发现空的大括号时,捕获组将被一个空的捕获组覆盖。

您可以了解这两种模式所需的步骤数(检查调试器):

original pattern

new pattern

注意:如果将 [^}{;]+ 包含在原子组中,可以改进您的原始模式。此更改会将所需的步骤数除以 2(与原来的相比),但即便如此,由于前面解释的原因,步骤数仍然很高。

(*) javascript 正则表达式引擎可能足够聪明,不会重试所有这些位置,但这只是一个假设。

关于c# - 大字符串正则表达式替换 C# 中的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28627645/

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