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

(первый постер, давний посетитель через Google)

Я пытаюсь извлечь содержимое некоторых квадратных скобок, однако у меня есть проблемы. У меня это работает для круглых скобок, как показано ниже, но я не вижу, как его следует изменить для работы с квадратными скобками. Я бы подумал, что замена круглого на квадратное и наоборот в этом примере должна работать, но, видимо, нет.

Он должен игнорировать скобки внутри скобок. Таким образом, он не вернет (11), а вернет (10 (11) 12).

$preg = '#\(((?>[^()]+)|(?R))*\)#x';
$str = '123(456)(789)(10(11)12)';

if(preg_match_all($preg, $str, $matches)) {
    $matches = $matches[0];
} else {
    $matches = array();
}

echo '<pre>'.print_r($matches,true).'</pre>';

This returns:

Array (
    [0] => (456)
    [1] => (789)
    [2] => (10(11)12)
)

Что идеально. Однако как я могу заставить это работать для строки с квадратными скобками, например:

$str = '123[456][789][10[11]12]'; 

person John Mellor    schedule 21.01.2010    source источник
comment
Когда я запускаю этот пример на своей машине, я фактически не получаю совпадений. PHP 5.2.6   -  person Peter Bailey    schedule 21.01.2010
comment
Ваш пример для круглых скобок у меня не работает.   -  person Stephen Melrose    schedule 21.01.2010
comment
хм, вы правы, я явно что-то сломал в своем тестировании, я перепроверю метод фигурных скобок, возможно, поэтому я не смог заставить его работать с квадратными скобками.   -  person John Mellor    schedule 21.01.2010
comment
Рабочее регулярное выражение для фигурных скобок: '#(((?›[^()]+)|(?R))*)#x'. Тот, который был опубликован, я взял в другом месте из своего Google, моя ошибка в публикации вопроса.   -  person John Mellor    schedule 21.01.2010
comment
Вам нужно обрабатывать случай нескольких вложенных скобок, например, [12[34[56]78]90]?   -  person Igor Korkhov    schedule 21.01.2010
comment
Да, это в основном моя проблема. Если это [12][34[56]] я только хочу вернуться; [12] и [34[56]]. Я не хочу [56].   -  person John Mellor    schedule 21.01.2010


Ответы (2)


Попробуй это:

$str = '123[456][789][10[11]12]';
$pattern = '/(([\d]+)|(\[[\d]+\])|\[[\d\[\]]+\])/';
preg_match_all($pattern,$str,$matches);
print_r($matches[0]);
//or
$str = '123[456][789][10[11]12]';
$pattern = '/(([\d]+)|(\[[\d]+\]))/';
preg_match_all($pattern,$str,$matches);
print_r($matches[0]);
person J. Martin    schedule 21.01.2010
comment
Спасибо за это, но первый, похоже, ограничен определенной глубиной. Например, попробуйте так: [123][456][789][10[11]12][141516][что-то еще]. Второй отделяет вложенные скобки. Так что вообще не работает в этом плане. - person John Mellor; 21.01.2010

person    schedule
comment
Похоже, это тоже не работает, если только мой тестовый код где-то неверен. Вот код и ответ: ‹pre› $preg = '/[(?:[^[]]+¦(?R))*]/'; $str = '123[456][789][10[11]12]'; if($count = preg_match_all($preg, $str, $matches)) { $matches = $matches[0]; } еще { $matches = array(); } echo $count.'‹pre›'.print_r($matches,true).'‹/pre›'; ‹/pre› Возвращает: ‹pre› 0 Массив ( ) ‹/pre› - person John Mellor; 21.01.2010
comment
@Alix Axel: он состоит из (?R), а )* в конце является частью большего выражения. - person Bandi-T; 21.01.2010
comment
Я скопировал ваш образец и изменил части, необходимые для работы с другими фигурными скобками. Однако, как вы, должно быть, заметили за это время (вы исправили это), в вашем примере кода был неправильный символ вертикальной черты. - person Lucero; 21.01.2010
comment
Это регулярное выражение работает для меня. Тестирование на spaweditor.com/scripts/regex дает именно тот результат, который я ожидал. - person Alan Moore; 21.01.2010
comment
Спасибо, теперь идеально. Извините за поздний ответ. Конец дня здесь. Для тех, кто обнаружит это в будущем, я не знаю, можно ли улучшить производительность, убедившись, что он возвращает только один массив, а не второй. Но помимо этого идеального, ответ принят. - person John Mellor; 22.01.2010