0

If you have a little time for me, here is my problem:


Example string:

{= $test->{$test->test}(). "it's a test {"} Conscripti esse nobis sic belli sic ab rationem in provinciis. {= $test2->{$test2->test}(). "it's another test {"} Et questi et ex vincula rapti quos autem in Chilo.
Cogitabatur est et coeptantem consenuit praepotens per consulta ne praepositus. {= $test3}

{= $test->{$test->{$test->test}}(). "it's a test {"} Conscripti esse nobis sic belli sic ab rationem in provinciis. {= $test2->{$test2->test}(). "it's another test {" : {} } Et questi et ex vincula rapti quos autem in Chilo.
Cogitabatur est et coeptantem consenuit praepotens per consulta ne praepositus. {= $test3}

Example of the expected result with preg_match_all function :

  • $test->{$test->test}(). "it's a test {"
  • $test2->{$test2->test}(). "it's another test {"
  • $test3

I need to find all between "{=" and "}" ; however, it may authorize :

  • "{" surrounded by single quotes ' and double "
  • "{}" as a pair is found
  • bonus, multiline between "{=" and "}"

For the moment i use this expression : /{=(\? )?([^}]+)}/ but i can found inside { or }.

I try : /{=\s+ ( ({[^}]*}) | [^}]+ )[^}]*}/x but it's wrong result : http://www.phpliveregex.com/p/52p

Thank you for your help.

2
  • 2
    I don't understand the problem. Can you elaborate? Perhaps give more example inputs and explain why they are/aren't valid? Commented Apr 28, 2014 at 15:19
  • 1
    Are you sure you need this!? rethink all the problem to the source... Commented Apr 28, 2014 at 15:20

2 Answers 2

2

This works for your test case:

{=.+?}(?!\(\s*\))

Don't hesitate to reply if you find issues ;)

Description

Regular expression visualization

Demo

http://regex101.com/r/yT2sM5

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you for your answer and the explanation with the link. But I complicated example, and don't work :/.
Hi, how is the picture generated? is it a tool?
0

You can build a pattern that describes the possible elements between {= and }:

$pattern= <<<'EOD'
~
(?(DEFINE)
      (?<quotes> '(?>[^'\\]++|\\.)*' | "(?>[^"\\]++|\\.)*" )
      (?<curly> { (?> \g<other> | \g<quotes> | \g<curly> )* } )
      (?<other> [^{}"']++ )
)

{= (?> \g<other> | \g<quotes> | \g<curly> )* } 

~xs
EOD;

preg_match_all ($pattern, $str, $matches);

print_r($matches[0]);

The (?(DEFINE)...) section of the pattern allows you to define named subpatterns without consuming any characters, as bricks you will use later.

(?<name> ...) defines a named subpattern. You can call it with \g<name> anywhere you want.

The main pattern (that consumes characters) is {= (?> \g<other> | \g<quotes> | \g<curly> )* }

About the "curly" named subpattern:

"quotes" and "other" are relatively easy to read. But "curly" that describes the possible content between curly brackets uses a recursive call to deal with nested curly brackets.

Note: this pattern works since curly brackets are balanced, but will give unexpected results if it is not the case. However, to deal with unbalanced curly brackets, you can change the pattern to:

~
(?(DEFINE)
      (?<quotes> '(?>[^'\\]++|\\.)*' | "(?>[^"\\]++|\\.)*" )
      (?<curly> { (?> \g<other> | \g<quotes> | \g<curly> | { )* } )
      (?<other> [^{}"']++ )
)

{= (?> \g<other> | \g<quotes> | \g<curly> | { )* } 

~xs

1 Comment

Thanks you, it's works fine. But can you explain, i don't know pattern in regex, it's magic !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.