2012-06-13 3 views
4

У меня есть строка, состоящая из нескольких предложений, которые находятся в фигурных скобках, которые я хочу удалить. Это было бы не так сложно (как я знаю сейчас), но настоящая проблема заключается в многоуровневости, и все, что я хочу разбить, это скобки верхнего уровня и оставить все в целости. Это выглядит примерно так:PHP, регулярные выражения и многоуровневые фигурные скобки

{Super duper {extra} text.} {Which I'm really {starting to} hate!} {But I {won't give up} so {easy}!} {Especially when someone is {gonna help me}.} 

Я хочу, чтобы создать массив, который будет состоять из этих четырех записей:

Super duper {extra} text. 
Which I'm really {starting to} hate! 
But I {won't give up} so {easy}! 
Especially when someone is {gonna help me}. 

Я пытался два пути, один был preg_split, который не сделал много хорошего :

$key = preg_split('/([!?.]{1,3}\} \{)/',$key, -1, PREG_SPLIT_DELIM_CAPTURE); 
$sentences = array(); 

for ($i=0, $n=count($key)-1; $i<$n; $i+=2) { 
$sentences[] = $key[$i].$key[$i+1]."<br><br>"; 
} 

Еще один использовал preg_match_all который был довольно хорошо, пока я не понял, что я имел эти скобки многоуровневые:

$matches = array(); 
$key = preg_match_all('/\{[^}]+\}/', $key, $matches); 
$key = $matches[0]; 

Заранее благодарен! :)

+0

Гарантируются ваши фигурные скобки должны быть сбалансированы? – ghoti

+0

@ghoti Да, они гарантированно сбалансированы. – moskalak

+0

@ Vulcan Я добавил информацию о том, что я пробовал в оригинальном посте. – moskalak

ответ

5

Вы можете использовать рекурсивное выражение как это:

/{((?:[^{}]++|(?R))*+)}/ 

Желаемые результаты будут в первой группе захвата.

Usage, что-то вроде:

preg_match_all('/{((?:[^{}]++|(?R))*+)}/', $str, $matches); 
$result = $matches[1]; 
+0

Редактировать: Он работает, и я получаю его, большое спасибо, сэр! Теперь мне нужно только понять, что именно делает это регулярное выражение. :) – moskalak

+0

@moskalak, элементы в '$ matches [1]'. Также добро пожаловать в SO, здесь лучший способ поблагодарить - это голосование. ;-) – Qtax

+0

и поэтому сделал. :) – moskalak

4
$x="foo {bar {baz}} whee"; 
$re="/(^[^{]*){(.*)}([^}]*)$/"; 
print preg_replace($re, "\\1\\2\\3", $x) . "\n";' 

возвращается:

foo bar {baz} whee 
+0

Благодарим вас за это предложение. Было бы здорово, но он возвращает строку, лишенную скобок верхнего уровня, в то время как мне действительно нужно создать массив, в котором каждая строка, заключенная в скобки на верхнем уровне, будет другой записью. – moskalak

Смежные вопросы