Eierschale
Eierschale

Reputation: 43

Pattern works on regex101 but not on Server

My pattern:

/{LOOP:(\w+)[^}]*}((\s*?.?)*?){\/LOOP:\1}/

My test string:

<tbody>
    {LOOP:MENU}
    <tr>
        <td>{VAR:ID}</td>
        <td>{VAR:NAME}</td>
        <td>{VAR:ROLLE}</td>
        <td>{VAR:ACTIONS}</td>
    </tr>
    {/LOOP:MENU}
</tbody>

When you try it on regex101 it is working without any problems. But when I try it on my Server with preg_match_all() it is not working. preg_last_error() returns:

2(PREG_BACKTRACK_LIMIT_ERROR).

How is that possible with regex101 telling me "1 Match in 581 Steps"? Or has the number of Steps nothing to do with Backtrack?

I'm using apache2 Server with PHP Version 5.5.9-1ubuntu4.16.

In my php.ini, pcre.backtrack_limit is set on 1000000.

EDIT:

Following the tip of Alan Moore, I now use the following pattern:

/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:\1}/s

This gives back 0(NO_ERROR). But on my server it is now not matching anything. Why is it working on regex101 but not on my server?

PHP:

$test="<tbody>
        {LOOP:MENU}
        <tr>
            <td>{VAR:ID}</td>
            <td>{VAR:NAME}</td>
            <td>{VAR:ROLLE}</td>
            <td>{VAR:ACTIONS}</td>
        </tr>
        {/LOOP:MENU}
       </tbody>"
preg_match_all("/{LOOP:(\w+)[^}]*}(.*?){\/LOOP:\1}/s", $test, $matches, PREG_SET_ORDER);
// $matches is now an emty array.

Upvotes: 0

Views: 295

Answers (2)

webb
webb

Reputation: 4340

php needs an extra backslash here and there in regexes. in this case, changing \1 to \\1 works:

preg_match_all("/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\\1)}/s", ...

alternatively, single backslash is ok here with single-quotes, and you can save some trouble by always using single quotes around regexes:

preg_match_all('/{LOOP:(\w+)[^}]*}(.*){\/LOOP:(\1)}/s', ...

Upvotes: 2

Ro Yo Mi
Ro Yo Mi

Reputation: 15010

It probably doesn't work because your server's regex engine handles { and } as special characters describing limited repetition (see also Regex Tutorial). Whereas the Regex101 page makes some assumptions.

When wanting to match { or } as characters, they'll need to be escaped like \{ or \} or tucked inside square brackets like [{}] then they're treated like regular characters.

I recommend escaping those characters like as follows:

\{LOOP:(\w+)[^}]*\}((\s*?.?)*?)\{\/LOOP:\1\}

This expression will also work in Regex101

Note: some flavors of regex will allow an unmatched } to be matches as a character, so it might not need to be escaped, however I found it's best practice to escape it.

Upvotes: 0

Related Questions