嵌套正则表达式的结果

时间:2015-01-25 18:18:07

标签: regex html-parsing

我正在解析像这样的HTML

<h3>Movie1</h3>
<div class="time"><span>10:00</span><span>12:00</span></div>
<h3>Movie2</h3>
<div class="time"><span>13:00</span><span>15:00</span><span>18:00</span></div>

我想让结果数组看起来像这样

0 => 
  0 => Movie1
  1 => Movie2
1 =>
  0 => 
    0 => 10:00
    1 => 12:00
  1 => 
    0 => 13:00
    1 => 15:00
    2 => 18:00

我可以分两步完成

1)通过regexp获取电影名称和整部电影的日程表,如此

~<h3>(.*?)</h3>(?:.*?)<div class="time">(.*?)</div>~s

2)像这样的regexp获取时间(我在第一步的每部电影的循环中都这样做)

~<span>([0-9]{2}:[0-9]{2})</span>~s

效果很好。 问题是:是否有一个正则表达式只在一个步骤中给出了相同的结果?

我尝试过像这样的嵌套组

~<h3>(.*?)</h3>(?:.*?)<div class="time">((<span>(.*?)</span>)*)</div>~s

我只收到每部电影的最后一次(仅限12:00和18:00)。

1 个答案:

答案 0 :(得分:1)

使用DOMDocument:

$dom = new DOMDocument;
$dom->loadHTML($html);

$xpath = new DOMXPath($dom);

$nodeList = $xpath->query('//h3|//div[@class="time"]/span');
$result = array();
$currentMovie = -1;

foreach ($nodeList as $node) {
    if ($node->nodeName === 'h3') {
        $result[0][++$currentMovie] = $node->nodeValue;
        continue;
    }
    $result[1][$currentMovie][] = $node->nodeValue;
}

print_r($result);

注意:为了更严格,您可以将xpath查询更改为:

//h3[following-sibling::div[@class="time"]] | //div[@class="time"]/span