I am getting PREG_JIT_STACKLIMIT_ERROR error in preg_replace_callback()
function when working with a bit longer string. Above 2000 characters it is not woking (above 2000 characters that match regex, not 2000 character string).
I've read already that it's caused by inefficient regex, but I can't make my regex simpler. Here's my regex:
/\{@([a-z0-9_]+)-((%?[a-z0-9_]+(:[a-z0-9_]+)*)+)\|(((?R)|.)*)@\}/Us
It should match strings like these:
1) {@if-statement|echo this|echo otherwise@}
2) {@if-statement:sub|echo this|echo otherwise@}
3) {@if-statement%statament2:sub|echo this@}
and also nested like this:
4) {@if-statement|echo this|
{@if-statement2|echo this|echo otherwise@}
@}
I've tried to simplify it to:
/\{@([a-z0-9_]+)-([a-z0-9_]+)\|(((?R)|.)*)@\}/Us
But it looks like error is caused by (((?R)|.)*)
part. Any advice?
Code for testing:
$string = '{@if-is_not_logged_homepage|
<header id="header_home">
<div class="in">
<div class="top">
<h1 class="logo"><a href="/"><img src="/img/logo-home.png" alt=""></a></h1>
<div class="login_outer_wrapper">
<button id="login"><div class="a"><i class="stripe"><i></i></i>Log in</div></button>
<div id="login_wrapper">
<form method="post" action="{^login^}" id="form_login_global">
<div class="form_field no_description">
<label>{!auth:login_email!}</label>
<div class="input"><input type="text" name="form[login]"></div>
</div>
<div class="form_field no_description password">
<label>{!auth:password!}</label>
<div class="input"><input type="password" name="form[password]"></div>
</div>
<div class="remember">
<input type="checkbox" name="remember" id="remember_me_check" checked>
<label for="remember_me_check"><i class="fa fa-check" aria-hidden="true"></i>Remember</label>
</div>
<div class="submit_box">
<button class="btn btn_check">Log in</button>
</div>
</form>
</div>
</div>
</div>
<div class="content clr">
<div class="main_menu">
<a href="">
<i class="ico a"><i class="fa fa-lightbulb-o" aria-hidden="true"></i></i>
<span>Idea</span>
<div> </div>
</a>
<a href="">
<i class="ico b"><i class="fa fa-user" aria-hidden="true"></i></i>
<span>FFa</span>
</a>
<a href="">
<i class="ico c"><i class="fa fa-briefcase" aria-hidden="true"></i></i>
<span>Buss</span>
</a>
</div>
<div class="text_wrapper">
<div>
<div class="register_wrapper">
<a id="main_register" class="btn register">Załóż konto</a>
<form method="post" action="{^login^}" id="form_register_home">
<div class="form_field no_description">
<label>{!auth:email!}</label>
<div class="input"><input type="text" name="form2[email]"></div>
</div>
<div class="form_field no_description password">
<label>{!auth:password!}</label>
<div class="input tooltip"><input type="password" name="form2[password]"><i class="fa fa-info-circle tooltip_open" aria-hidden="true" title="{!auth:password_format!}"></i></div>
</div>
<div class="form_field terms no_description">
<div class="input">
<input type="checkbox" name="form2[terms]" id="terms_check">
<label for="terms_check"><i class="fa fa-check" aria-hidden="true"></i>Agree</label>
</div>
</div>
<div class="form_field no_description">
<div class="input captcha_wrapper">
<div class="g-recaptcha" data-sitekey="{%captcha_public_key%}"></div>
</div>
</div>
<div class="submit_box">
<button class="btn btn_check">{!auth:register_btn!}</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</header>
@}';
$if_counter = 0;
$parsed_view = preg_replace_callback( '/\{@([a-z0-9_]+)-((%?[a-z0-9_]+(:[a-z0-9_]+)*)+)\|(((?R)|.)*)@\}/Us',
function( $match ) use( &$if_counter ){
return '<-{'. ( $if_counter ++ ) .'}->';
}, $string );
var_dump($parsed_view); // NULL