【问题标题】:Two successive preg_match两个连续的 preg_match
【发布时间】:2011-02-08 12:58:36
【问题描述】:

我正在尝试使用两个 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 返回正确的值:&lt;span class="first"&gt;First&lt;/span&gt;。但是第二个print_r,不是返回&lt;span class="second"&gt;this one&lt;span&gt;,而是返回&lt;div class="second"&gt;Not this one&lt;/span&gt;

所以我猜preg_match 函数从头开始处理,而不是最后一个preg_match 调用。

如何让preg_match 的第二次(第三次、第四次等)呼叫在最后一次呼叫时运行?

谢谢,

问候。

【问题讨论】:

  • 你可以使用 preg_match_all。
  • 如何在我的情况下使用 preg_match_all?谢谢。

标签: php regex preg-match


【解决方案1】:

要连续调用preg_match,继续搜索您上次离开的位置,请使用PREG_OFFSET_CAPTURE 标志:

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

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

【讨论】:

    【解决方案2】:

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

    int preg_match ( string $pattern, string $subject [, array &amp;$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); 
    

    【讨论】:

      【解决方案3】:

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

      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]);
      

      【讨论】:

        猜你喜欢
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多