3

假设我有这样一段文字:

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

在这里,我想要的是只解析要解析的<item>s 的两个顶层,并将结果以这样的数组返回给我:

[0] = "foo bar foo bar  <item>child item</item>"
[1] = "second item  <item>second child </item>";

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

这是我使用的模式:

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

有任何想法吗?

编辑:这不适用于 HTML,它适用于我无法使用任何 dom 解析器的自定义内部脚本语言。所以请建议一个正则表达式解决方案。

4

3 回答 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>
)
于 2012-11-16T20:49:33.450 回答
1

正则表达式不太适合您正在做的事情。如果你走这条路,你可能会比你走一条不同的路花更多的时间。我建议你检查一个 DOM 解析器。下面的一个相当容易使用,应该可以满足您的基本需求。

PHP 简单的 HTML DOM 解析器

另请查看这个问题,因为它会为您提供其他选择。

于 2012-11-16T20:29:17.390 回答
0

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

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

%<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 )
于 2016-12-09T10:23:07.703 回答