preg_match_all 对于嵌套元素
preg_match_all for nested element
这是一种BB码。知道如何匹配 [LI]text[/LI] 和 [UL]text[/UL] 等所有元素吗?
preg_match_all("/(\[UL].*\[\/UL])|(\[LI].*\[\/LI])/", '[UL][LI]sadas[/LI][/UL]', $match);
想收到类似的东西:
0 => "[UL][LI]sadas[/LI][/UL]"
1 => "[UL][LI]sadas[/LI][/UL]"
2 => "[LI]sadas[/LI]" <--- This is not captured now.
基本上是关于:如何获得这个 [LI]text[/LI] 部分而不是松散的 [UL]text[/UL] 部分?
要做到这一点,您需要两件事:
- 递归子模式(捕获组中引用自身的子模式)
- 将此递归模式放入先行断言中(因为断言不消耗字符,并且使用此技巧,您可以多次匹配相同的子字符串)
~(?=(\[(\w+)]([^[]*(?:(?1)[^[]*)*?)\[/]))~
(?=...)
是先行断言。 (当前位置后接...)
(\[(\w+)]([^[]*(?:(?1)[^[]*)*?)\[/])
是捕获组 1。
(?1)
引用捕获组 1 中的子模式。
指的是捕获组2(标签名)的匹配。
这是一种BB码。知道如何匹配 [LI]text[/LI] 和 [UL]text[/UL] 等所有元素吗?
preg_match_all("/(\[UL].*\[\/UL])|(\[LI].*\[\/LI])/", '[UL][LI]sadas[/LI][/UL]', $match);
想收到类似的东西:
0 => "[UL][LI]sadas[/LI][/UL]"
1 => "[UL][LI]sadas[/LI][/UL]"
2 => "[LI]sadas[/LI]" <--- This is not captured now.
基本上是关于:如何获得这个 [LI]text[/LI] 部分而不是松散的 [UL]text[/UL] 部分?
要做到这一点,您需要两件事:
- 递归子模式(捕获组中引用自身的子模式)
- 将此递归模式放入先行断言中(因为断言不消耗字符,并且使用此技巧,您可以多次匹配相同的子字符串)
~(?=(\[(\w+)]([^[]*(?:(?1)[^[]*)*?)\[/]))~
(?=...)
是先行断言。 (当前位置后接...)
(\[(\w+)]([^[]*(?:(?1)[^[]*)*?)\[/])
是捕获组 1。
(?1)
引用捕获组 1 中的子模式。
指的是捕获组2(标签名)的匹配。