如何使用正则表达式解析仅嵌套标签的第一层?

3

假设我有一段文本如下:

<item>
   foo bar foo bar 
   <item> child item </item>
</item>
<item>
   second item
   <item> second child </item>
</item>

这里,我希望只解析两个顶层的<item>,并将结果以以下数组形式返回给我:
[0] = "foo bar foo bar  <item>child item</item>"
[1] = "second item  <item>second child </item>";

然而在我的测试中,由于子级别的<item>标签匹配了该模式,它们也被包含在内,导致我得到了一个4元素数组,而不是我想要的2元素数组。

这是我使用的模式:

%<item>(.+)</item>%si

有什么想法吗?

编辑:这不是HTML,而是一个自定义的内部脚本语言,不能使用任何DOM解析器。因此,请建议一个正则表达式解决方案。


这不是用于 HTML 的,而是用于自定义脚本语言,我不能使用任何 DOM 解析器。 - Ali
1
很抱歉,@jeroen,它不是结构化的XML,正如你从示例中所看到的那样。 - Ali
@mario 如果您想发布一个详细的答案,我会接受它。 - Ali
它是用于自定义内部脚本语言的,我不能使用任何dom解析器。它是用什么语言构建的?你不能在其中利用libxml吗? - DaveRandom
@jeroen 用户提供的内容中没有任何字符被转义。 - Ali
显示剩余11条评论
3个回答

3
%<p>(.+?)^</p>%smi

编辑

$text = "<item> foo bar foo bar <item> child item </item> </item> <item> second item <item> second child </item> </item>";
preg_match_all('%<item>(.*?<item>.*?</item>).*?</item>%si', $text, $matches);
print_r($matches[1]);

输出

Array
(
    [0] =>  foo bar foo bar <item> child item </item>
    [1] =>  second item <item> second child </item>
)

1
它能够工作,但是如果我调整行的顺序,将所有标签放在同一行上,那么它就停止工作了。 - Ali
你在不断地挪动目标门柱 :P - keyboardSmasher
如果我在主要的<item>标签内放置多个嵌套的<item>标签,那么它会再次失败。 - Ali

1

正则表达式并不适合你正在做的事情。如果你选择这条路,你可能会花费比选择其他路线更多的时间。我建议你尝试使用DOM解析器。下面这个解析器相当容易使用,应该能够满足你的基本需求。

PHP Simple HTML DOM Parser

此外,还要查看this question,因为它将为你提供其他选择。


这不是针对HTML的,而是针对一种自定义脚本语言,我不能使用任何DOM解析器。 - Ali
你能否提供一个完整的自定义语言部分的真实示例? - Jordan Mack
这与问题无关。我已经发布了与我需要做的相关的内容。 - Ali

0

你说输入不是HTML,但提供了一个看起来像HTML的字符串。正则表达式最适合用于纯文本,而不是标记文本。你没有透露这种类型输入背后的真实语言,因此,我可以建议的解决方案基于这样的假设:在元素节点之间,<字符不能作为字面量出现(只能作为某些实体)。

这意味着,你可以使用否定字符类[^<]并将*量词应用于它:

%<item>([^<]+)</item>%i

请查看正则表达式演示, PHP演示:

$text = "<item> foo bar foo bar <item> child item </item> </item> <item> second item <item> second child </item> </item>";
preg_match_all('%<item>([^<]*)<item>%i', $text, $matches);
print_r($matches[1]);
// => Array ( [0] =>  foo bar foo bar  [1] =>  second item )

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