如果标签之间没有任何内容,我该如何匹配?

时间:2017-06-28 08:40:23

标签: php regex

我知道。通过RegEx解析HTML是一种错误的方法。但老实说,我没有时间学习使用PHP DOM解析器。所以,请回答我的问题。

以下是my current pattern

<a href="(.*?)"><li>[\s\S]+?<img src="([^"]+)[\s\S]+?<p>([^<]+)[\s\S]+?<s([^>]+)([^<]+)<\/span>

它几乎可以工作。只有最后一个捕获组与>标记的<span>匹配。虽然想要匹配<span>标记的值。我怎样才能做到这一点? (通常<span>没有任何价值,因此它不应该匹配任何内容)

注意到在模式中添加pan>会导致灾难性回溯错误。我的意思是:

<a href="(.*?)"><li>[\s\S]+?<img src="([^"]+)[\s\S]+?<p>([^<]+)[\s\S]+?<span>([^>]+)([^<]+)<\/span>
/* ---------------------------- added -----------------------------------^^^^

2 个答案:

答案 0 :(得分:2)

我认为这应该有所帮助。 (假设您要分析的文件是您在regex101中放入的文件,并且您想要的字段是您尝试在正则表达式中提取的字段)

<?php
$doc = new DOMDocument();
$doc->loadHTMLFile("testfile.html");
$xpath = new DOMXpath($doc);
$links = $xpath->query("//ul[@class='users']/a");
$result = array();
if (!is_null($links)) {
  foreach ($links as $link) {
    $href = $link->getAttribute('href');
    $img = $xpath->query("li/img", $link)[0];
    $img_src = $img->getAttribute('src');
    $p = $xpath->query("li/p", $link)[0];
    $p_text = $p->textContent;
    $span = $xpath->query("li/span", $link)[0];
    $span_text = $span->textContent;
    $result[] = [$href, $img_src, $p_text, $span_text];
  }
}
print_r($result);

答案 1 :(得分:2)

首先,这就是提出问题的方式:

  

在以下示例HTML数据中:

<a href="profile/xalil">
  <li>
    <img src="../users/avatar/small/thumb_default.jpg" />
    <p>xalil eshghi</p>
    <span></span>
  </li>
</a>
     

我想找到hrefimg srcp的值   内容和span内容。

     

我尝试使用以下regexp .........

正如您所知,使用正则表达式the wrong approach。您可以通过替换以下内容来“修复”您的正则表达式解决方案:

<s([^>]+)([^<]+)<\/span>

使用:

<span>([^<]*)<\/span>

......但是,这不仅难以阅读,而且还没有考虑到各种可能的边缘情况。

一些简单示例:如果HTML被注释掉,或者它使用单引号,或img标记在src之前是否包含其他属性,该怎么办?由于您在模式中使用[\s\S]+,您可能还会遇到更多关键问题 - 这可能会导致正则表达式跳转到完全不同的HTML部分!

使用DOM解析器可以而且应该很容易解决这个问题。这样的事情:

<?php
// This is just some boilerplate code for the sake of completion...
$doc = new DOMDocument();
$doc->loadHTMLFile("your_page.html");
$xpath = new DOMXpath($doc);

// Do you want to scope your results to within <ul class="users"> ?
// If not, just use: $links = $xpath->query("//a");
$links = $xpath->query("//ul[@class='users']/a");

// Guard clause
if (is_null($links)) { return; }

$result = array();
foreach ($links as $link) {
  $href = $link->getAttribute('href');      // PART 1 - Get the href
  $img = $xpath->query("li/img", $link)[0];
  $img_src = $img->getAttribute('src');     // PART 2 - Get the img src
  $p = $xpath->query("li/p", $link)[0];
  $p_text = $p->textContent;                // PART 3 - Get the p contents
  $span = $xpath->query("li/span", $link)[0];
  $span_text = $span->textContent;          // PART 4 - get the span contents
  $result[] = [$href, $img_src, $p_text, $span_text];
}
print_r($result);
?>

解决这样的问题不仅更容易阅读和维护,而且它可以解决您使用正则表达式方法所带来的所有潜在错误。