PHP、正则表达式和多级花括号

5

我有一个字符串,其中包含几个用花括号括起来的句子,我想要删除这些括号。这看起来并不难(现在我知道了),但真正困难的是它是多层级的,并且我只想去掉顶层括号,保留里面的所有内容。它看起来像这样:

{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];

提前感谢您!:)


你的花括号是否保证平衡? - ghoti
@ghoti 是的,它们保证是平衡的。 - moskalak
@Vulcan,我已经在原帖中添加了我尝试过的信息。 - moskalak
顶级大括号总是由单个空格分隔吗? - nickb
2个回答

5
您可以使用如下的递归表达式:

{expression}

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

期望的结果将在第一个捕获组中。

用法类似于:

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

编辑:它可以工作并且我明白了,非常感谢您,先生!现在我只需要理解这个正则表达式到底是做什么的。 :) - moskalak
@moskalak,$matches[1]中的元素。欢迎来到SO,在这里最好的感谢方式是投票。;-) - Qtax

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

返回:

foo bar {baz} whee

谢谢您提供这个建议。这很好,但它返回一个剥离了顶层括号的字符串,而我真正需要创建一个数组,在该数组中,每个在顶层括号内的字符串都将成为另一个条目。 - moskalak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接