可以从字符串中获取嵌套花括号中的所有内容吗?例如:
{quick}棕色狐狸{跳过{懒}狗
所以我需要:
从大多数嵌套开始,这个顺序更好。
答案 0 :(得分:8)
下面的正则表达式将允许您获取所有嵌套花括号的内容。请注意,这假设嵌套的花括号是平衡的;否则,很难定义答案应该是什么。
(?=\{((?:[^{}]++|\{(?1)\})++)\})
结果将是捕获第1组。
请注意,订单不是问题中指定的。打印出的订单由开口大括号{
的外观顺序定义,这意味着最外面的一对内容将首先打印出来。
暂时忽略零宽度正面预测 (?=pattern)
,让我们专注于内部模式,即:
\{((?:[^{}]++|\{(?1)\})++)\}
2个文字花括号之间的部分 - ((?:[^{}]++|\{(?1)\})++)
将匹配 1个或更多个实例:
[^{}]++
或{}
所包含的块,该块可能包含许多其他非大括号序列或其他块。上面的模式可以匹配不包含{}
的文本,这是我们不需要的。因此,我们确保匹配是{}
由两端的大括号{}
包围的块:\{((?:[^{}]++|\{(?1)\})++)\}
。
由于我们想要所有嵌套花括号内的内容,我们需要阻止引擎使用文本。这就是使用零宽度正向前瞻的地方。
由于您将重做嵌套大括号的匹配,因此效率不高,但我怀疑还有其他通用解决方案带有正则表达式可以有效地处理它。
普通代码可以一次性有效地处理所有内容,如果您将来要扩展您的需求,建议使用。
答案 1 :(得分:4)
一次传递中不使用正则表达式的简单解决方案:
$str = 'The {quick} brown fox {jumps {over the} lazy} dog';
$result = parseCurlyBrace($str);
echo '<pre>' . print_r($result,true) . '</pre>';
function parseCurlyBrace($str) {
$length = strlen($str);
$stack = array();
$result = array();
for($i=0; $i < $length; $i++) {
if($str[$i] == '{') {
$stack[] = $i;
}
if($str[$i] == '}') {
$open = array_pop($stack);
$result[] = substr($str,$open+1, $i-$open-1);
}
}
return $result;
}
答案 2 :(得分:3)
你可以试试这个:
$subject = 'The {quick} brown fox {jumps {over the} lazy} dog';
function nestor($subject) {
$result = false;
preg_match_all('~[^{}]+|\{(?<nested>(?R)*)\}~', $subject, $matches);
foreach($matches['nested'] as $match) {
if ($match != "") {
$result[] = $match;
$nesty = nestor($match);
if ($nesty)
$result = array_merge($result,$nesty);
// $result[]=$nesty; // to preserve the hierarchy
}
}
return $result;
}
print_r(nestor($subject));
此处使用的模式与嵌套结构匹配,但无法以大于1的深度进行捕获。 这就是为什么nestor函数被递归地应用于每个匹配的原因。
您可以使用\ G功能探索另一种使用此其他模式的方式:
$subject = 'The {quick} brown fox {jumps {over the}{ fat} lazy} dog';
$pattern = '~[^{}]++|\G\{(?<nested>(?R)*+)\}~';
preg_match_all($pattern, $subject, $matches/*, PREG_SET_ORDER*/);
print_r($matches);
如果查看结果,可以轻松确定规则以了解每个元素的级别深度。
答案 3 :(得分:1)
你可以用一种黑客,丑陋的方式做到如下:
1)搜索正则表达式{([^}]*)}
2)搜索正则表达式{([^}]*{[^}]*}[^}]*)}
的所有匹配项(如您所见,这可以动态构建)
3)搜索正则表达式{([^}]*{[^}]*{[^}]*}[^}]*}[^}]*)}
的所有匹配项...(继续动态构建它,直到没有匹配)
捕获组由()
s表示,位于外部{}
对内,将允许您仅抓取第一个捕获组中的内容而不是整个正则表达式匹配。