regex - 在perl RE中将。*视为。{0,1024}的任何方法?

标签 regex perl optimization

为了过滤电子邮件,我们允许一些用户提供的RE。早期,当与任意大的电子邮件进行匹配时,我们遇到了一些包含RE的性能问题,例如,包含.*。我们发现一个简单的解决方案是对用户提供的RE上的s/\*/{0,1024}/进行编码。但是,这不是一个完美的解决方案,因为它会破坏以下模式:

/[*]/

除了想出一些复杂的方法来解决用户提供的RE输入的每种可能的变化外,我还想限制perl对*+字符的解释,使其最大长度为1024个字符。

有什么办法吗?

最佳答案

更新

在量词前添加了(?<!\\),因为转义的* +不应匹配。如果存在\\*(匹配\ 0次或多次),替换仍将失败。

一个改进是

s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/
s/(?<!\\)\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/

看到它here on Regexr

这意味着匹配[*+],但前提是前面没有结束的],并且在此之前没有[。并且在方括号之前不允许\((?<!\\)部分)。
(?! ... )是否定的前瞻
(?<! ... )是负面的回望

有关详细信息,请参见perlretut

更新2包括所有格修饰语
s/(?<!(?<!\\)[\\+*?])\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/   # for +
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/    # for *

看到它here on Regexr

似乎正在工作,但现在变得越来越复杂!

关于regex - 在perl RE中将。*视为。{0,1024}的任何方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8517657/

相关文章:

optimization - 创建掩蔽 kreg 值的有效方法

java - 如何编写 Java 代码以允许使用 SSE 和边界检查消除(或其他高级优化)?

regex - Excel公式中的正则表达式

perl - 在这种情况下,< 在 Perl 中做了什么?

perl - 有没有更好的方法在 Perl 中通过引用传递?

c++ - 是否可以在 C++ 中检测操作系统?

java - 损坏发生后会发生去优化吗?

javascript - 仅使用 JavaScript 中的正则表达式选择第一个破折号

regex - 为什么我的 Perl 正则表达式使用这么多内存?

.net - 修复Youtube URL RegEx(.NET ReGex引擎语法)