Получить все вхождения слов между фигурными скобками

У меня есть текст вроде:

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

Мне нужно получить

demo  
test

Примечание. Мой текст может содержать более одного блока {}, не всегда два. Пример:

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

Я использовал это выражение /{([^}]*)}/ с preg_match, но он возвращает только первое слово, а не все слова внутри текста.

Ответ 1

Используйте preg_match_all:

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

Это то же самое, что и preg_match, со следующими оговорками:

Ищет предмет для всех совпадений с регулярным выражением, указанным в pattern и помещает их в совпадения в порядке, указанном флагами.

После того, как найдено первое совпадение, последующие поиски продолжаются от конца последнего матча.

Ответ 2

Ваше выражение верное, но вместо этого вы должны использовать preg_match_all(), чтобы получить все совпадения. Вот рабочий пример того, что будет выглядеть:

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

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

Чтобы также зафиксировать позиции каждого совпадения, вы можете передать PREG_OFFSET_CAPTURE в качестве четвертого параметра в preg_match_all. Чтобы использовать это, вы можете использовать следующий пример:

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

Ответ 3

Поскольку элементы { и } являются частью синтаксиса соответствия регулярному выражению, вам необходимо избежать этих символов:

<?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);
?>

производит

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

Этот пример может быть полезен для понимания использования фигурных скобок в регулярных выражениях:

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

который возвращает:

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

Обратите внимание, что '34' исключается из результатов, потому что \d{3,} требует соответствия по меньшей мере трех последовательных цифр.

Ответ 4

Согласование частей между двумя фигурными скобками с использованием RegEx менее эффективно, чем использование Stack для этой цели. Использование RegEx было бы чем-то вроде "быстрого и грязного патча", но для синтаксического анализа и обработки входной строки вы должны использовать стек. Посетите здесь для концепции и здесь для применения этого же.