父亲中的PHP preg_match_all元素?

时间:2013-03-05 12:32:44

标签: php regex preg-match

编辑:

似乎人们认为我正在尝试解析HTML,而我已经重复了几次我正在尝试解析日志<option>结构< strong>与我的日志类似。

我的日志看起来像这样:

!# [2013-03-04 14:51:31] // cluster1 BEGIN \\ 
!## apache: 41
!## mysql: 31
!## tomcat: 81
!## lotus: 985
!# [2013-03-04 14:51:56] // cluster1 END \\ 
!# [2013-03-04 14:51:56] // cluster2 BEGIN \\ 
!## apache: 13
!## mysql: 61
!## tomcat: 6
!## lotus: 513
!# [2013-03-04 14:52:13] // cluster2 END \\ 

我无法让这个正则表达式工作,也许这是不可能的......需要帮助:)

基本上我试图一次性从父实体中重新编写多个子元素。为简洁起见,我将使用下拉列表<select> HTML元素作为示例。这实际上将用于日志解析,但我还不确定它究竟是什么格式,并且dropdown元素尽可能接近我需要的而不必解释日志的结构。

所以我们假设我们有一个下拉列表:

<select class="parent">
    <option value="1">First child</option>
    <option value="2">Second child</option>
    <option value="3">Third child</option>
    ...
</select>

要从父级中分离<option>个元素,我会使用它:

preg_match_all('/<select class="parent">(.*)<\/select>/is', $source, $matches);

哪个好。但是现在我必须做一秒preg_match()来过滤掉我的<option>元素,所以它看起来像这样:

preg_match_all('/<option value="(.*?)" >(.*?)<\/option>/is', $matches['1'], $finalMatches);

我的结果很好。但有没有办法将两个命令合并为一个规则?所以它会找到父元素,在这种情况下是<select class="parent">*</select>块,并过滤掉在该父元素中找到的每个<option value="*">*</option>条目?然后,我将留下一个完美的父子组合数组,而不是迭代第一个结果,然后让每个迭代完成另一个preg_match函数。

1 个答案:

答案 0 :(得分:2)

我认为这就是你要找的东西:

preg_match_all(
    '~(?:<select class="parent">|\G)\s*<option value="(.*?)">(.*?)</option>~i',
    $source, $matches);

\G将匹配锚定到上一个匹配结束的位置(如果之前没有匹配,则匹配到输入的开头)。因此,第一个匹配将包含开始<select>标记和第一个<option>元素,之后的每个匹配将包含 next <option>元素 - 它赢了不要在后面的<select>元素中找到匹配项。

<强> Here's a demo 即可。我还使用了\K匹配启动重置运算符,但这不是必需的;我只是认为它使输出更容易阅读。它有效地将之前的一切变成了积极的外观,没有通常的限制。