有一个包含许多href的html代码。但我不需要所有的hrefs。我想只获得div中包含的href:
<div class="category-map second-links">
*****
</div> <p class="sec">
我希望看到的结果是:
<a href='xxx'>yyy</a>
<a href='zzz'>www</a>
...
我的版本(不工作):
(?<=<div class=\"category-map second-links\">)(.+?(<a href=\".+?".+?>.+<\/a>))+(?=<\/div> <p class="sec">)
答案 0 :(得分:3)
免责声明:您最好使用正确的HTML解析器。这个答案是出于教育目的,虽然它比普通的正则表达式更可靠,如果它是有效的html:P
所以我决定分两部分来做这件事:
<div class="category-map second-links"></div>
中的所有内容,即使它已嵌套。<a></a>
,我选择保持简单,因为我不希望链接嵌套。所以这是正则表达式,我们将使用递归模式和xsi
修饰符:
<div\s+class\s*=\s*"\s*category-map\s+second-links\s*"\s*> # match a certain div with a certain classes
(?: # non-capturing group
(?:<!--.*?-->)? # Match the comments !
(?:(?!</?div[^>]*>).) # check if there is no start/closing tag
| # or (which means there is)
(?R) # Recurse the pattern, it's the same as (?0)
)* # repeat zero or more times
</div\s*> # match the closing tag
(?=.*?<p\s+class\s*=\s*"\s*sec\s*"\s*>) # make sure there is <p class="sec"> ahead of the expression
<强>改性剂:强>
s
:在模式中使用点元字符匹配所有字符,包括换行符。x
:模式中的空白数据字符完全被忽略,除非转义或在字符类中,并且字符类外的未转义#
与下一个换行符(包括在内)之间的字符是也被忽略了。这相当于Perl的/x
修饰符,并且可以在复杂的模式中包含注释。i
:匹配不区分大小写的如果没有像a
这样的疯狂内容,匹配未使用的<a title="</a>"></a>
代码并不困难:
<a[^>]*> # match the beginning a tag
.*? # match everything ungreedy until ...
</a\s*> # match </a > or </a>
# Not forgetting the xsi modifiers
$input = '<div class="category-map second-links">
*****
<!--<div class="category-map second-links"> Comment hacks -->
<div class="category-map second-links">
<a href=\'xxx\'>yyy</a>
<a href=\'zzz\'>www</a>
...
</div>
<div class="category-map second-links">
*****
<!--<div class="category-map second-links"> Comment hacks -->
<div class="category-map second-links">
<a href=\'aaa\'>bbb</a>
<a href=\'ccc\'>ddd</a>
...
</div>
</div> <p class="sec">';
$links = array();
preg_match_all('~
<div\s+class\s*=\s*"\s*category-map\s+second-links\s*"\s*> # match a certain div with a certain classes
(?: # non-capturing group
(?:<!--.*?-->)? # Match the comments !
(?:(?!</?div[^>]*>).) # check if there is no start/closing tag
| # or (which means there is)
(?R) # Recurse the pattern, it\'s the same as (?0)
)* # repeat zero or more times
</div\s*> # match the closing tag
(?=.*?<p\s+class\s*=\s*"\s*sec\s*"\s*>) # make sure there is <p class="sec"> ahead of the expression
~sxi', $input, $matches);
if(isset($matches[0])){
foreach($matches[0] as $match){
preg_match_all('~
<a[^>]*> # match the beginning a tag
.*? # match everything ungreedy until ...
</a\s*> # match </a > or </a>
~isx', $match, $tempLinks);
if(isset($tempLinks[0])){
array_push($links, $tempLinks[0]);
}
}
}
if(isset($links[0])){
print_r($links[0]);
}else{
echo 'empty :(';
}
答案 1 :(得分:2)
如果将HTML加载到DOM文档中,则可以使用Xpath从中查询节点。
文档中的所有元素:
//a
它有一个祖先/父div元素:
//a[ancestor:div]
使用类属性category-map second-links
//a[ancestor::div[@class = "category-map second-links"]]
获取已过滤元素的href属性(可选)
//a[ancestor::div[@class = "category-map second-links"]]/@href
完整示例:
$html = <<<'HTML'
<div class="category-map second-links">
*****
<!--<div class="category-map second-links"> Comment hacks -->
<div class="category-map second-links">
<a href='xxx'>yyy</a>
<a href='zzz'>www</a>
...
</div>
<div class="category-map second-links">
*****
<!--<div class="category-map second-links"> Comment hacks -->
<div class="category-map second-links">
<a href='aaa'>bbb</a>
<a href='ccc'>ddd</a>
...
</div>
</div> <p class="sec">
HTML;
$dom = new DOMDocument();
$dom->loadHtml($html);
$xpath = new DOMXpath($dom);
// fetch the href attributes
$hrefs = array();
foreach ($xpath->evaluate('//a[ancestor::div[@class = "category-map second-links"]]/@href') as $node) {
$hrefs[] = $node->value;
}
var_dump($hrefs);
// fetch the a elements an read some data from them
$linkData = array();
foreach ($xpath->evaluate('//a[ancestor::div[@class = "category-map second-links"]]') as $node) {
$linkData[] = array(
'href' => $node->getAttribute('@href'),
'text' => $node->nodeValue,
);
}
var_dump($linkData);
// fetch the a elements and store their html
$links = array();
foreach ($xpath->evaluate('//a[ancestor::div[@class = "category-map second-links"]]') as $node) {
$links[] = $dom->saveHtml($node);
}
var_dump($links);
答案 2 :(得分:1)
// Create DOM from URL
$html = file_get_html('<YOU_WEBSITE_URL_HERE>');
// Find specific tag
foreach($html->find('div.category-map.second-links a') as $anchor) {
$anchors[] = $anchor;
}
print_r($anchors);
答案 3 :(得分:1)
如果您想使用Regex,那么您可能会使用两个正则表达式查询 一个用于获取所有div,每个div中的第二个找到href。
因为在这样的单一查询中
"<div.*?<a href='(?<data>.*?)'.*?</div>"
如果任何div有多个href,你将只获得一个href。
所以你可以用dom
来做到这一点$dom->find('div a')->attrib('href');
我不确定上面的dom是%100工作但是我给你这个,因为暗示希望你可以为你做一个