更新:
如果您可能正在使用嵌套的“标签”,我可能会选择这样的东西:
$pattern = '/(\[\s*([^\]]++)\s*\])(?=(.*?)(\[\s*\/\s*\2\s*\]))/';
正如您可能知道的那样,这与 CasimiretHippolyte 的建议没有什么不同(只有他的正则表达式 AFAIKT 不会在如下场景中捕获外部标签:)
his is content that is a sample.
[md] Special Content [foo]Piece[/foo] [/md]
This is some more content.
然而,使用这个表达式,$matches
看起来像:
大批 (
0 =>
大批 (
0 => '[md]',
1 => '[foo]',
),
1 =>
大批 (
0 => '[md]',
1 => '[foo]',
),
2 =>
大批 (
0 => 'md',
1 => '富',
),
3 =>
大批 (
0 => ' 特殊内容 [foo]Piece[/foo] ',
1 => '片',
),
4 =>
大批 (
0 => '[/md]',
1 => '[/foo]',
),
)
一个相当简单的模式来匹配看起来像这样的所有子字符串[foo]sometext[/foo]
$pattern = '/(\[[^\/\]]+\])([^\]]+)(\[\s*\/\s*[^\]]+\])/';
if (preg_match_all($pattern, $content, $matches))
{
echo '<pre>';
print_r($matches);
echo '</pre>';
}
输出:
大批 (
0 =>
大批 (
0 => '[md] 特殊内容片段 [/md]',
),
1 =>
大批 (
0 => '[md]',
),
2 =>
大批 (
0 => '特殊内容片段',
),
3 =>
大批 (
0 => '[/md]',
),
)
这种模式是如何工作的:它分为三组。
第一个:(\[[^\/\]]+\])
匹配开头和结尾[]
,中间的所有内容既不是右括号也不是正斜杠。
第二个: '([^]]+)' 匹配第一个非字符组之后的每个字符[
第三个:(\[\s*\/\s*[^\]]+\])
匹配一个开头[
,后跟零个或多个空格,一个正斜杠,再后跟零个或多个空格,以及任何其他不是的字符]
如果你想匹配一个特定的结束标签,但保持相同的三个组(第四个),使用这个(稍微复杂一点)表达式:
$pattern = '/(\[\s*([^\]]+?)\s*\])(.+?)(\[\s*\/\s*\2\s*\])/';
这将返回:
大批 (
0 =>
大批 (
0 => '[md] 特殊内容片段 [/md]',
),
1 =>
大批 (
0 => '[md]',
),
2 =>
大批 (
0 => 'md',
),
3 =>
大批 (
0 => '特殊内容片段',
),
4 =>
大批 (
0 => '[/md]',
),
)
请注意,第 2 组(我们在表达式中使用 as 的\2
那个)是“标记名”本身。