2

One of these days where I'm about to question my sanity again...

I don't understand why my regex refuses to match for the optional line break. Code:

$string = 'this is some template {$code}. nice! 
{$varinnewline}
{if $bla}1{else}2{/if}
';

echo "<pre>";
preg_replace_callback("/\{([^\}]*)\}(\r\n)?/Us", function($matches) {
  print_r($matches);
}, $string);

It produces (among others) this output:

Array
(
    [0] => {$varinnewline}
    [1] => $varinnewline
)

and not this (which it does if I remove the 0-1 match ? at the end of the regex):

Array
(
    [0] => {$varinnewline}

    [1] => $varinnewline
    [2] => 
)

Basically I want a regex that matches the \r\n at the end of the line if it is available. (I need that because after transforming the {} into < ?php ?> the new line after the ?> seems to be removed by the php interpreter)

Tyron
  • 1,863
  • 10
  • 26

1 Answers1

3

See a post I answered awhile back explaining this.

But to answer your question, apart from \r and \n PCRE also has another character group matching newlines, you can use a nifty escape sequence for this case which is \R.

\R matches a generic newline; that is, anything considered a linebreak sequence by Unicode. This includes all characters matched by \v (vertical whitespace) and the multi character sequence \x0D\x0A.

preg_replace_callback("~\{([^\}]*)\}(\R)?~", function($matches) {
    print_r($matches);
}, $string);

Output

Array
(
    [0] => {$code}
    [1] => $code
)
Array
(
    [0] => {$varinnewline}

    [1] => $varinnewline
    [2] => 

)
Array
(
    [0] => {if $bla}
    [1] => if $bla
)
Array
(
    [0] => {else}
    [1] => else
)
Array
(
    [0] => {/if}

    [1] => /if
    [2] => 

)
Community
  • 1
  • 1
hwnd
  • 65,661
  • 4
  • 77
  • 114
  • Oh, that is interesting. You have found the problem, but not by what you claim ;-) Your regex also works with \r\n and non utf-8. It looks like the ungreedy modifier is the culprit. Which is strange because i tried inverting it locally with (?U) and that didn't work. Thanks a bunch! – Tyron May 12 '14 at 16:00
  • Interesting, is the u-modifier required for the proper use of `\R` ? – Jonny 5 May 12 '14 at 18:49
  • 1
    @Jonny5 See a post I answered [here](http://stackoverflow.com/questions/18988536/php-regex-how-to-match-r-and-n-without-using-r-n/18992691#18992691) – hwnd May 12 '14 at 20:21