Php 正则表达式仅与特定类匹配完整超链接

Php 正则表达式仅与特定类匹配完整超链接,php,regex,dom,hyperlink,Php,Regex,Dom,Hyperlink,我有一个字符串,里面有一些超链接。我只想与正则表达式匹配来自所有正则表达式的特定链接。我不知道是href还是类先到,可能会有所不同。 例如,这是一个刺: <div class='wp-pagenavi'> <span class='pages'>Page 1 of 8</span><span class='current'>1</span> <a href='http://stv.localhost/channel/politic

我有一个字符串,里面有一些超链接。我只想与正则表达式匹配来自所有正则表达式的特定链接。我不知道是href还是类先到,可能会有所不同。 例如,这是一个刺:

<div class='wp-pagenavi'>
<span class='pages'>Page 1 of 8</span><span class='current'>1</span>
<a href='http://stv.localhost/channel/political/page/2' class='page'>2</a>     
<a href='http://stv.localhost/channel/political/page/3' class='page'>3</a>ccccc<a href='http://stv.localhost/channel/political/page/4' class='page'>4</a><a href='http://stv.localhost/channel/political/page/5' class='page'>5</a><a href="http://stv.localhost/channel/political/page/2" class="nextpostslink">»eee</a><span class='extend'>...</span><a href='http://stv.localhost/channel/political/page/8' class='last'>lastן »</a>
<a class="cccc">xxx</a>
</div>

第1页,共81页
ccccc。。。
这个正则表达式是我能得到的最接近的-

/<a\s?(href=)?('|")(.*)('|") class=('|")nextpostslink('|")>.{1,6}<\/a>/

/这将在php中工作:

/<a[^>]+href=(\"|')([^\"']*)('|\")[^>]+class=(\"|')[^'\"]*nextpostslink[^'\"]*('|\")[^>]*>(.{1,6})<\/a>/m
/
ccccc。。。
ccccc。。。
xxx
排爆药;
$regexp=“/(]+class=(\“\”)[^'\“]*nextpostslink[^'\”]*(“\\”[^>]*>(.{1,6}))/m”;
$matches=array();
if(preg_match($regexp,$html,$matches)){
$link=$matches[0];
$text=$matches[4];
$regexp=“/href=(\“\”)([^'\“]*)(\“\”)/”;
$matches=array();
if(preg_match($regexp,$html,$matches)){
$url=$matches[2];
回显“URL:$URL\n”;
回显“Text:$Text\n”;
}
}
当然,您可以通过匹配这两个变体中的一个来扩展regexp(class-first vs-href-first),但这会很长,而且我认为这不会提高性能

作为概念证明,我创建了一个不关心顺序的regexp:

/<a[^>]+(href=(\"|')([^\"']*)('|\")[^>]+class=(\"|')[^'\"]*nextpostslink[^'\"]*(\"|')|class=(\"|')[^'\"]*nextpostslink[^'\"]*(\"|')[^>]+href=(\"|')([^\"']*)('|\"))[^>]*>(.{1,6})<\/a>/m
/]+(href=(\“\”)([^\”)([^\”[^>]+class=(\“\”)[^')[^'”]*nextpostslink[^'\”]*(\“\”)(\“\”)(class=(\“\”)[^'”]*nextpostslink[^']*(\“\”)[^>]+href=(\“\”)([^\”)([^\”)*)([^>)*)([^>)([^>)*”)([^>)”)([^>)*)([^>)(^>)

文本将位于第12组,URL将位于第3组或第10组,具体取决于顺序。

这将在php中起作用:

/<a[^>]+href=(\"|')([^\"']*)('|\")[^>]+class=(\"|')[^'\"]*nextpostslink[^'\"]*('|\")[^>]*>(.{1,6})<\/a>/m
/
ccccc。。。
ccccc。。。
xxx
排爆药;
$regexp=“/(]+class=(\“\”)[^'\“]*nextpostslink[^'\”]*(“\\”[^>]*>(.{1,6}))/m”;
$matches=array();
if(preg_match($regexp,$html,$matches)){
$link=$matches[0];
$text=$matches[4];
$regexp=“/href=(\“\”)([^'\“]*)(\“\”)/”;
$matches=array();
if(preg_match($regexp,$html,$matches)){
$url=$matches[2];
回显“URL:$URL\n”;
回显“Text:$Text\n”;
}
}
当然,您可以通过匹配这两个变体中的一个来扩展regexp(class-first vs-href-first),但这会很长,而且我认为这不会提高性能

作为概念证明,我创建了一个不关心顺序的regexp:

/<a[^>]+(href=(\"|')([^\"']*)('|\")[^>]+class=(\"|')[^'\"]*nextpostslink[^'\"]*(\"|')|class=(\"|')[^'\"]*nextpostslink[^'\"]*(\"|')[^>]+href=(\"|')([^\"']*)('|\"))[^>]*>(.{1,6})<\/a>/m
/]+(href=(\“\”)([^\”)([^\”[^>]+class=(\“\”)[^')[^'”]*nextpostslink[^'\”]*(\“\”)(\“\”)(class=(\“\”)[^'”]*nextpostslink[^']*(\“\”)[^>]+href=(\“\”)([^\”)([^\”)*)([^>)*)([^>)([^>)*”)([^>)”)([^>)*)([^>)(^>)
文本将位于第12组,URL将位于第3组或第10组,具体取决于顺序。

我将(.*)替换为[^'”]+,如下所示:

<a\s*(href=)?('|")[^'"]+('|") class=('|")nextpostslink('|")>.{1,6}</a>

注意:我在RegEx Buddy中尝试了这个方法,因此我不需要逃避's或/

我将(.*)替换为[^'”+,如下所示:

<a\s*(href=)?('|")[^'"]+('|") class=('|")nextpostslink('|")>.{1,6}</a>


注意:我在RegEx Buddy上试过这个方法,所以我不需要逃避或/

使用真正的HTML解析器更好。放弃在HTML上使用正则表达式的所有尝试

改用PHP的:


为此,最好使用真正的HTML解析器。放弃在HTML上使用正则表达式的所有尝试

改用PHP的:


不确定这是否就是你想要的,但无论如何:用正则表达式解析html是个坏主意。使用xpath实现以达到所需的元素。以下xpath表达式将为您提供类为“nextpostlink”的所有“a”元素:

这里有大量的xpath信息,因为您没有提到您的编程语言,这里有一个使用java的快速xpath教程:

编辑:


php+xpath+html:

不确定这是否就是您想要的,但无论如何:用正则表达式解析html是个坏主意。使用xpath实现以达到所需的元素。以下xpath表达式将为您提供类为“nextpostlink”的所有“a”元素:

这里有大量的xpath信息,因为您没有提到您的编程语言,这里有一个使用java的快速xpath教程:

编辑:



php+xpath+html:

问题是通过regex获取,这里是如何
问题是通过regex获取,这里是如何

不使用regex解析html。你用什么语言编程?不要用正则表达式来解析HTML。你用什么语言编程?我使用php并尝试使用preg_match函数。但在此之前,我只是对这个伟大的正则表达式助手做了一些测试——找出正确的表达式。太好了!这句话似乎很管用。但是,由于这是自动生成的html,我不能假设href总是在类之前。有没有办法让这个表达式在两种情况下都起作用(href在课前或课后出现)?谢谢!它看起来正在执行我使用php所需的过程,并尝试使用preg_match函数。但在此之前,我只是对这个伟大的正则表达式助手做了一些测试——找出正确的表达式。太好了!这句话似乎很管用。但是,由于这是自动生成的html,我不能假设href总是在类之前。有没有办法让这个表达式在两种情况下都起作用(href在课前或课后出现)?谢谢!它看起来正在做所需的处理这将是一个巨大的性能打击,我只建议这是速度真的不是问题,或者是否会做进一步的处理。@Nicklas Claptrap。(1) DOMDocument速度惊人。(2) 不要过早地优化。(3) DOMDocument可以工作,而regex可能(偶尔)可以工作。我认为用页面的所有html实例一个新对象会有点过分。页面有巨大的html,这只是页面的一小部分。@Maor在长字符串上使用正则表达式也不会有很好的性能。说真的,不要在这个问题上使用正则表达式。它将是不可靠的,当HTML稍微改变时,它将中断,并且会让你偏头痛。使用为该工作设计的工具。我意识到我可以将这个字符串作为DOMDocument实例加载,所以我不必加载所有页面的html
$dom = new DOMDocument;
$dom->loadHTML($yourHTML);

foreach ($dom->getElementsByTagName('a') as $link) {
    $classes = explode(' ', $link->getAttribute('class'));

    if (in_array('nextpostslink', $classes)) {
        // $link has the class "nextpostslink"
    }
}
//a[contains(@class,"nextpostslink")]