kapitanluffy
kapitanluffy

Reputation: 1267

Looping within a regular expression

can regex able to find a patter to this?

{{foo.bar1.bar2.bar3}}

where in the groups would be

$1 = foo $2 = bar1 $3 = bar2 $4 = bar3 and so on..

it would be like re-doing the expression over and over again until it fails to get a match.

the current expression i am working on is

(?:\{{2})([\w]+).([\w]+)(?:\}{2})

Here's a link from regexr.

http://regexr.com?3203h

--

ok I guess i didn't explain well what I'm trying to achieve here.

let's say I am trying to replace all

.barX inside a {{foo . . . }}

my expected results should be

$foo->bar1->bar2->bar3

Upvotes: 2

Views: 99

Answers (4)

Tim Pietzcker
Tim Pietzcker

Reputation: 336418

This should work, assuming no braces are allowed within the match:

preg_match_all(
    '%(?<=     # Assert that the previous character(s) are either
     \{\{      # {{
    |          # or
     \.        # .
    )          # End of lookbehind
    [^{}.]*    # Match any number of characters besides braces/dots.
    (?=        # Assert that the following regex can be matched here:
     (?:       # Try to match
      \.       #  a dot, followed by
      [^{}]*   #  any number of characters except braces
     )?        # optionally
     \}\}      # Match }}
    )          # End of lookahead%x', 
    $subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];

Upvotes: 3

Johny Skovdal
Johny Skovdal

Reputation: 2104

I don't know the correct syntax in PHP, for pulling out the results, but you could do:

\{{2}(\w+)(?:\.(\w+))*\}{2}

That would capture the first hit in the first capturing group and the rest in second capturing group. regexr.com is lacking the ability to show that as far as I can see though. Try out Expresso, and you'll see what I mean.

Upvotes: 0

Alex Kalicki
Alex Kalicki

Reputation: 1533

I don't think so, but it's relatively painless to just split the string on periods like so:

$str = "{{foo.bar1.bar2.bar3}}";
$str = str_replace(array("{","}"), "", $str);
$values = explode(".", $str);

print_r($values);  // Yields an array with values foo, bar1, bar2, and bar3

EDIT: In response to your question edit, you could replace all barX in a string by doing the following:

$str = "{{foo.bar1.bar2.bar3}}";
$newStr = preg_replace("#bar\d#, "hi", $str);

echo $newStr; // outputs "{{foo.hi.hi.hi}}"

Upvotes: 1

npinti
npinti

Reputation: 52185

I'm not a PHP person, but I managed to construct this piece of code here:

preg_match_all("([a-z0-9]+)",
"{{foo.bar1.bar2.bar3}}",
$out, PREG_PATTERN_ORDER);

foreach($out[0] as $val)
{
echo($val);
echo("<br>");
}

The code above prints the following:

foo 
bar1
bar2
bar3

It should allow you to exhaustively search a given string by using a simple regular expression. I think that you should also be able to get what you want by removing the braces and splitting the string.

Upvotes: 1

Related Questions