我知道。通过RegEx解析HTML是一种错误的方法。但老实说,我没有时间学习使用PHP DOM解析器。所以,请回答我的问题。
<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 -----------------------------------^^^^
答案 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>
我想找到
href
,img src
,p
的值 内容和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);
?>
解决这样的问题不仅更容易阅读和维护,而且它可以解决您使用正则表达式方法所带来的所有潜在错误。