两个连续的preg_match

时间:2011-02-08 12:58:36

标签: php regex preg-match

我正在尝试使用两个preg_match,以便从html源代码中获取两个特定值。

<?php

    $url = "http://www.example.com";
    $userAgent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1";
    $ch = curl_init();
    curl_setopt($ch,CURLOPT_USERAGENT,$userAgent);
    curl_setopt($ch,CURLOPT_URL,$url);
    curl_setopt($ch,CURLOPT_AUTOREFERER,true);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
    curl_setopt($ch,CURLOPT_TIMEOUT,10000000);  
    $html  = curl_exec($ch);
    preg_match('~<span class="first">(.*)<\/span>~msU',$html,$matching_data);
    preg_match('~<span class="second">(.*)<\/span>~msU',$html,$matching_data2);
    print_r($matching_data);
    print_r($matching_data2);   
?>

考虑到$html var包含以下序列:

<title>foobar title</title>
<body>
<div class="second">Not this one</span>
<div>
<span class="first">First</span>
<span class="second">this one<span>
</div>
</body>

如果我运行php代码,则第一个print_r会返回正确的值:<span class="first">First</span>。但是第二个print_r,而不是返回<span class="second">this one<span>,它返回<div class="second">Not this one</span>

所以我想preg_match函数从头开始而不是最后一次preg_match调用开始治疗。

如何在最后一次通话中进行preg_match的第二次(第三次,第四次等)通话?

谢谢,

问候。

3 个答案:

答案 0 :(得分:3)

要对preg_match进行连续调用,继续搜索上次停止的位置,请使用PREG_OFFSET_CAPTURE标记:

http://php.net/manual/en/function.preg-match.php

对于较大的问题,正则表达式通常不适合解析HTML。你应该使用某种DOM解析器为你做这项工作,如果你甚至需要在服务器端做这项工作。这种事情可以使用JavaScript在客户端非常简单(并且自然地)完成 - 您只需将相关值传回服务器。

答案 1 :(得分:0)

你可以在preg_match函数中使用偏移捕获和偏移参数(php:preg_match

int preg_match ( string $pattern, string $subject [, array &$matches [, int $flags [, int $offset]]] )

试试这个:

<?php

...

preg_match('~<span class="first">(.*)<\/span>~msU',$html,$matching_data,PREG_OFFSET_CAPTURE);
preg_match('~<span class="second">(.*)<\/span>~msU',$html,$matching_data2,PREG_OFFSET_CAPTURE, $matching_data[0][1]+strlen($matching_data[0][0]));
print_r($matching_data);
print_r($matching_data2); 

答案 2 :(得分:0)

该HTML是您需要使用的代码吗?它不是有效的HTML。您可以使用preg_match_all作为@igorw建议:

preg_match_all('~<(span|div) class="(first|second)">(.*)<\/?span>~msU', $html,$matching_data);
echo '<xmp>'; print_r($matching_data[0]);

但如果HTML有效:

<title>foobar title</title>
<body>
<span class="second">Not this one</span>
<div>
<span class="first">First</span>
<span class="second">this one</span>
</div>
</body>

preg_match_all('~<span class="(first|second)">(.*)<\/span>~msU', $html, $matching_data);
echo '<xmp>'; print_r($matching_data[0]);