PHP 7 preg_replace PREG_JIT_STACKLIMIT_ERROR with simple string

前端 未结 1 1534
逝去的感伤
逝去的感伤 2020-12-21 23:49

I know other people have submitted questions around this error, however I can\'t see how this regex or the subject string could be any simpler.

To me this is a bug,

相关标签:
1条回答
  • 2020-12-21 23:59

    IMPORTANT NOTE:
    The (.|\n)*? or (.|\r?\n)*? patterns should be avoided as they cause too much redundant backtracking. To match any char, you usually may use . with a DOTALL flag, or, in JavaScript, you may use [^] or [\s\S] constructs. See How do I match any character across multiple lines in a regular expression? for more details.

    Current Issue

    The (.|\n(?!\n))*? pattern is very inefficient and causes a lot of redundant backtracking when used not at the end of the pattern (where it does not make sense at all). The more it is located to the left of the pattern, the worse is the performance.

    Since all it does is matches any char but a newline and then a newline that is not followed with another newline, in a lazy way, you may re-write the pattern as .*?(?:\R(?!\R).*?)*:

    '~\b_([^_\n\t ].*?(?:\R(?!\R).*?)*)_\b~'
    

    See the regex demo.

    Note:

    • (?<=[^\w]|^) = \b because there is a _ (a word char) after the lookbehind
    • (?=[^\w]|$) = \b because there is a _ before the lookahead
    • .*?(?:\R(?!\R).*?)* - matches:
      • .*? - any 0+ chars other than line break chars, as few as possible, then
      • (?:\R(?!\R).*?)* - zero or more sequences of:
        • \R(?!\R) - a line break sequence not followed with another line break sequence (\R = \n, \r\n or \r)
        • .*? - any 0+ chars other than line break chars, as few as possible
    0 讨论(0)
提交回复
热议问题