Frank
Frank

Reputation: 141

Get all occurrences of words between curly brackets

I have a text like:

This is a {demo} phrase made for {test}

I need to get

demo  
test

Note: My text can have more than one block of {}, not always two. Example:

This is a {demo} phrase made for {test} written in {English}

I used this expression /{([^}]*)}/ with preg_match but it returns only the first word, not all words inside the text.

Upvotes: 13

Views: 8698

Answers (4)

Ja͢ck
Ja͢ck

Reputation: 173642

Your expression is correct, but you should be using preg_match_all() instead to retrieve all matches. Here's a working example of what that would look like:

$s = 'This is a {demo} phrase made for {test}';

if (preg_match_all('/{([^}]*)}/', $s, $matches)) {
        echo join("\n", $matches[1]);
}

To also capture the positions of each match, you can pass PREG_OFFSET_CAPTURE as the fourth parameter to preg_match_all. To use that, you can use the following example:

if (preg_match_all('/{([^}]*)}/', $s, $matches, PREG_OFFSET_CAPTURE)) {
        foreach ($matches[1] as $match) {
            echo "{$match[0]} occurs at position {$match[1]}\n";
        }
}

Upvotes: 11

Cylian
Cylian

Reputation: 11182

Matching portions between pair of braces using RegEx, is less better than using Stack for this purpose. Using RegEx would be something like «quick and dirty patch», but for parsing and processing input string you have to use a stack. Visit here for the concept and here for applying the same.

Upvotes: 0

rorycl
rorycl

Reputation: 1384

As the { and } are part of regex matching syntax, you need to escape these characters:

<?php
$text = <<<EOD
this {is} some text {from}
which I {may} want to {extract}
some words {between} brackets.
EOD;
preg_match_all("!\{(\w+)\}!", $text, $matches);
print_r($matches);
?>

produces

Array
(
    [0] => Array
        (
            [0] => {is}
            [1] => {from}
            [2] => {may}
            [3] => {extract}
            [4] => {between}
        )
     ... etc ...
)

This example may be helpful to understand the use of curly brackets in regexes:

<?php
$str = 'abc212def3456gh34ij';
preg_match_all("!\d{3,}!", $str, $matches);
print_r($matches);
?>

which returns:

Array
(
    [0] => Array
        (
            [0] => 212
            [1] => 3456
        )
)

Note that '34' is excluded from the results because the \d{3,} requires a match of at least 3 consecutive digits.

Upvotes: 3

Grant Thomas
Grant Thomas

Reputation: 45058

Use preg_match_all instead:

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

It's much the same as preg_match, with the following stipulations:

Searches subject for all matches to the regular expression given in pattern and puts them in matches in the order specified by flags.

After the first match is found, the subsequent searches are continued on from end of the last match.

Upvotes: 15

Related Questions