【发布时间】:2022-01-23 08:05:31
【问题描述】:
我们遇到这样一种情况,即在开始时使用单个字符进行通配符搜索,然后在通配符之后使用其他字符,并且运行速度非常慢(至少在 c# 中)。 有没有这样做的原因和改进的方法?在几乎所有其他情况下它都更快。
20k 长随机字符串的示例运行 1000 次:
- a.*r1 耗时:1802
- r1.*耗时:9
- r1.*b.*c 耗时:9
- r1f.*b.*c 耗时:16
- a.*r1f.*c 耗时:3199
- a.*r1.*c 耗时:1895
- a.*b.*r1f 耗时:55450
它绝对不是随机字符串,因为尝试了不同的字符串。
模式肯定是,如果第一部分是单个字符,然后是通配符后面的任何字符,它总是慢得多。
--更新--
我想知道 Regex 的工作方式是否是循环查找该单个字符,当它找到它时,它会一直搜索直到结束寻找下一个模式。当它没有找到它时,它会返回第一个字符并开始寻找下一个第一个字符,直到它再次找到第一个匹配并执行一些完整的逻辑,即使它可以跳过它在第一次运行时传递的所有那些字符.
我想我已经通过生成一个不带字符“a”的随机字符串来确认这一点——如果我使用这个字符作为第一个字符,它真的很快,但如果我使用“c”它很慢。即 a.*b.*r1f 在这种情况下是即时的,但 c.*b.*r1f 需要很长时间。
如果想知道您是否可以在正则表达式中以某种方式对其进行优化?
【问题讨论】:
-
您没有在其中任何一个中进行单字符通配符搜索。单个字符通配符搜索将只是
.(如果它是可选的.?),而不是.*(匹配任何字符零次或更多次)。 -
没错 - 它不是一个字符。实际上,我们正在寻找 [介于两者之间的任何东西] 然后 r1(在第一个示例中)
-
那不应该是一个非贪婪的通配符搜索
.*?吗? -
也许这就是答案 - 我真的不知道这意味着什么 - 我真的会这样做。*?而不是 .*
标签: c# regex performance