0

I use this pattern:

'/({for) (\d+) (times})([\w+\d+{}]{0,})({endfor})/i'

to convert

{for 3 times}App2{endfor}

in

App2  App2  App2 

But this do not work with:

{for 7 times}
    App2
{endfor}

This is a little piece of my very little template engine.

It's just for fun

$mactos = Array(
    '/({for) (\d+) (times})([\w+\d+{}]{0,})({endfor})/i' => '<?php for($i=0;$i<${2};$i++) : ?> ${4} <?php endfor; ?' . '>',
    '/({{)(\w+)(}})/i' => '<?php echo $${2}; ?' . '>'
);
$php = file_get_contents('teamplate.php');
foreach ($this->getPatternAndReplacement() as $pattern => $replacement) {
    $php = preg_replace($pattern, $replacement, $php);
}

I've read that (...) catch anything but with

'/({for) (\d+) (times})(...)({endfor})/i'

does not work =(.

sensorario
  • 15,862
  • 24
  • 85
  • 131
  • Side note: Most metacharacters lose special meaning inside character classes, so you're allowing literal `+` chars. Assuming you don't mean to accept literal `+` chars, `[\w+\d+{}]{0,}` appears to be equivalent to `[\w{}]*` (since `*` means `{0,}` and `\d` is included within `\w`). – Wiseguy Nov 27 '12 at 22:12

1 Answers1

2

If you literally mean (...), that is a group that matches exactly three characters. (.+) would match one or more of any characters, except...


By default, . matches anything except newlines.

s (PCRE_DOTALL)
If this modifier is set, a dot metacharacter in the pattern matches all characters, including newlines. Without it, newlines are excluded.

Use the s modifier to allow . to match newline characters.

/your pattern/s

Example (also here):

$str = <<<STR
{for 7 times}
    App2
{endfor}
STR;

preg_match('/({for) (\d+) (times})(.+)({endfor})/s', $str, $matchParts);

print_r($matchParts);
OUTPUT:

Array
(
    [0] => {for 7 times}
    App2
{endfor}
    [1] => {for
    [2] => 7
    [3] => times}
    [4] => 
    App2

    [5] => {endfor}
)
Wiseguy
  • 19,067
  • 8
  • 59
  • 78
  • It's ok, but I'll like to understand why does not work with two for like:$str = << – sensorario Nov 27 '12 at 22:44
  • Ok: I dont need to create yet another template engine. This work it's just for fun. Thank you Wiseguy. – sensorario Nov 27 '12 at 22:46
  • @SimoneDemoGentili Thanks. To answer your question, `preg_match()` only matches once; you want `preg_match_all()` for multiple matches. Also, you would make your wildcard `(.+)` lazy (ungreedy) like this `(.+?)` so it will not match too far. See [example here](http://codepad.viper-7.com/cfWo19). – Wiseguy Nov 27 '12 at 22:51
  • @SimoneDemoGentili Experimenting for fun is great learning! :-) By the way, something like a template engine might be too complex for a single regex, so you'd probably be better off writing your own parser/tokenizer for it. – Wiseguy Nov 27 '12 at 22:52
  • you use preg_match* functions instead of preg_replace. Why? You suggest me to pass through preg_match*? – sensorario Nov 28 '12 at 00:13
  • @SimoneDemoGentili Oh, no, I thought you meant why my example didn't match multiple. Do note the lazy quantifier. That's probably key. – Wiseguy Nov 28 '12 at 00:15
  • This answer has been added to the [Stack Overflow Regular Expression FAQ](http://stackoverflow.com/a/22944075/2736496), under "Modifiers". – aliteralmind Apr 10 '14 at 00:37