Jaylen
Jaylen

Reputation: 40301

How to find all matching patterns in a string using PHP?

I have a string that looks like this

Hello, my name is "{{ @sql(SELECT TOP 1 name FROM table1 WHERE [id] = 5 ) }}" and my title is "{{ @sql(SELECT TOP 1 title FROM table1 WHERE [id] = 5 ) }}"

I need to be able to take this string and parse out any pattern that matches the following pattern {{ @sql(WHATEVER QUERY GOES HERE) }} it must start with two braken followed by optional spaces and then @sql( ending in ) }}

Additionally, I will also need to extract the inner query which is the text that is found between @sql( and ending in ) }} Here is what I have done

$pattern = '/\{\{\s*+@sql\((.+)\)+\s*+\}\}/i';

$matches = [];

preg_match    ( $pattern, $subject, $matches, PREG_OFFSET_CAPTURE );
echo '<pre>';
print_r($matches);
echo '</pre>';

My pattern works for the following string

Hello "{{ @sql(SELECT TOP 1 name FROM table1 WHERE [id] = 5 ) }}" 

but when I need to use the pattern more than once in the text, it seems that my pattern search for the last occurrence of )}} instead of the next occurrence.

How can I update my pattern so it looks for one ore multiple matches?

Thank you

Upvotes: 2

Views: 291

Answers (3)

Jan
Jan

Reputation: 43169

After some discussion in the comments, I guess you need preg_replace():

<?php
$string = 'Hello, my name is "{{ @sql(SELECT TOP 1 name FROM table1 WHERE [id] = 5 ) }}" and my title is "{{ @sql(SELECT TOP 1 title FROM table1 WHERE [id] = 5 ) }}"';

$regex = '~
            \{{2}\h*@sql\(    # start of outer part
            (?P<query>[^()]+) # inner query
            \)\h*\}{2}        # end of outer part
        ~x';

$string = preg_replace($regex, '$1', $string);
echo $string;
# Hello, my name is "SELECT TOP 1 name FROM table1 WHERE [id] = 5 " and my title is "SELECT TOP 1 title FROM table1 WHERE [id] = 5 "

?>

See a demo on ideone.com.

Upvotes: 1

Navkar Jain
Navkar Jain

Reputation: 16

One way that I do it is this: You don't want any other braces within one pair of opening and closing braces. So you can specify this:

[^\{\}]+

The above pattern will match any string of characters that does not contain a curly bracket. Your complete pattern would be

/\{\{ ?@sql\([^\{\}]+\) ?\}\}/i

Upvotes: 0

nicael
nicael

Reputation: 18995

You should just make the regex non-gready, by adding ?

...(.+?)...

(And also use preg_match_all)

Upvotes: 0

Related Questions