我们允许一些用户提供的RE用于过滤电子邮件。早期我们在与任意大型电子邮件进行匹配时,会遇到包含.*
的RE的一些性能问题。我们在用户提供的RE上找到了s/\*/{0,1024}/
的简单解决方案。但是,这不是一个完美的解决方案,因为它会破坏以下模式:
/[*]/
而不是想出一些复杂的方法来解释用户提供的RE输入的每个可能的突变,我想限制perl对*
和+
字符的解释最大长度为1024个字符。
有没有办法做到这一点?
答案 0 :(得分:5)
这并不能真正回答您的问题,但您应该了解用户提供的正则表达式的其他问题,例如请参阅此summary at OWASP。根据您的具体情况,编写或查找自定义简单模式匹配库可能更好?
答案 1 :(得分:4)
<强>更新强>
在量词之前添加了(?<!\\)
,因为转义的* +不应该匹配。如果有\\*
(匹配\
0次或更多次),则替换仍然会失败。
这将是一个改进
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/
s/(?<!\\)\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/
这意味着匹配[*+]
,但前提是前面没有关闭]
,之前没有[
。在方括号前面不允许\
((?<!\\)
部分)。
(?! ... )
是一个负面的预测
(?<! ... )
是一个负面的背后隐藏
有关详细信息,请参阅perlretut
更新2包括占有量词
s/(?<!(?<!\\)[\\+*?])\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/ # for +
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/ # for *
似乎正在发挥作用,但它现在变得越来越复杂了!
答案 2 :(得分:4)
使用Regexp::Parser获取树并根据需要修改正则表达式,或者为Regexp::English提供GUI界面
答案 3 :(得分:1)
你的意思是除了修补源码之外?