Regex 有没有办法在perl RE中把.*当作{01024}处理?
我们允许一些用户提供的REs用于过滤电子邮件。早些时候,当匹配任意大的电子邮件时,我们在REs中遇到了一些性能问题,例如,Regex 有没有办法在perl RE中把.*当作{01024}处理?,regex,perl,optimization,Regex,Perl,Optimization,我们允许一些用户提供的REs用于过滤电子邮件。早些时候,当匹配任意大的电子邮件时,我们在REs中遇到了一些性能问题,例如,*。我们发现一个简单的解决方案是在用户提供的RE上使用s/\*/{01024}/。但是,这不是一个完美的解决方案,因为它将打破以下模式: /[*]/ 我想将perl对*和+字符的解释限制为1024个字符的最大长度,而不是提出一些复杂的方法来解释用户提供的重新输入的每一种可能的变异 有什么方法可以做到这一点吗?你的意思是除了修补源代码之外 您可以将输入文本分成较短的块,并仅匹
*
。我们发现一个简单的解决方案是在用户提供的RE上使用s/\*/{01024}/
。但是,这不是一个完美的解决方案,因为它将打破以下模式:
/[*]/
我想将perl对*
和+
字符的解释限制为1024个字符的最大长度,而不是提出一些复杂的方法来解释用户提供的重新输入的每一种可能的变异
有什么方法可以做到这一点吗?你的意思是除了修补源代码之外
更新 在量词前添加了一个
(?,因为转义的*+不应匹配。如果存在\\*
(匹配\
0次或更多次),则替换仍将失败
这将是一个改进
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/
s/(?<!\\)\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/
看到了吗
似乎正在工作,但现在它变得非常复杂!这并不能真正回答您的问题,但您应该注意用户提供的正则表达式的其他问题,例如,请参见此。根据您的具体情况,编写或查找自定义的简单模式匹配库可能更好?使用并根据需要修改regex,或提供GUI界面以yes…而不是修补源代码:)(在某些情况下,我们仍然需要标准行为,不涉及用户输入)这些过滤器在电子邮件的哪个部分运行?头部,身体?@fge:body才是最重要的,因为这是一个可以任意大的部分。我们也会检查标题,但一次只能检查一个标题。即使是最长的电子邮件头也不够长,不足以导致*和+。好的,还有另一个问题:您是在整个内容上运行这些正则表达式,包括附件,还是跳过附件?@fge:我们在所有mime部分上运行它,并使用文本内容类型(text/plain、text/html、vcards和少量其他类型)禁止*
和+
,并指示用户改用{n,m}
?这个上限是32766。是的,这是一个改进。。。它仍然保留“所有格”+量词的情况(即*+
,++
,?++
和{..}+
)。我想在这些情况下,我也可以形成一个类似的方法来忽略+字符。所有格量词的优点是,添加了一个解决方案。谢谢。。。我完全同意你最后的评论。。。事情肯定越来越复杂了!我希望有一个$MAX\u REGEXP\u STRING\u LENGTH的perlvar,或者什么的!:)@ikegami我在我的帖子顶部指出,作为限制,+1,因为^(a | aa){0,30}$
足以让正则表达式引擎在数百万个周期内保持忙碌,字符串类似aaaaaaaaaaaaaaaaaaaax
谢谢;一个很好的警告。虽然用户实际上可以自己做,但实际上他们只能自己做。因此,我们的主要目标是防止他们意外地这样做代码>块,但是。。。
s/(?<!(?<!\\)[\\+*?])\+(?!(?<!\\)[^[]*?(?<!\\)\])/{1,1024}/ # for +
s/(?<!\\)\*(?!(?<!\\)[^[]*?(?<!\\)\])/{0,1024}/ # for *