用于在<a> and </a>标记之间查找所有内容的正则表达式

时间:2008-12-05 07:23:52

标签: php regex pattern-matching

我正在尝试找到一种方法来列出<a></a>标记之间的所有内容。所以我有一个链接列表,我想得到链接的名称(不是链接的位置,而是它们在页面上调用的内容)。对我来说真的很有帮助。

目前我有这个:

$lines = preg_split("/\r?\n|\r/", $content);  // content is the given page
foreach ($lines as $val) {
  if (preg_match("/(<A(.*)>)(<\/A>)/", $val, $alink)) {     
    $newurl = $alink[1];

    // put in array of found links
    $links[$index] = $newurl;
    $index++;
    $is_href = true;
  }
}

9 个答案:

答案 0 :(得分:14)

标准免责声明适用:使用正则表达式解析HTML并不理想。成功取决于逐个字符级别的输入的良好形成。如果你不能保证这一点,正则表达式将无法在某些时候做正确的事情。

说完了:

<a\b[^>]*>(.*?)</a>   // match group one will contain the link text

答案 1 :(得分:3)

我是正则表达的忠实粉丝,但这不适合使用它们。

使用真正的HTML解析器。

  • 您的代码会更清晰
  • 更有可能工作

我用Google搜索了一个PHP HTML解析器,找到了this one

如果你知道你正在使用XHTML,那么你可以使用PHP的标准XML解析器。

答案 2 :(得分:2)

<a\s*(.*)\>(.*)</a>

<a href="http://www.stackoverflow.com">Go to stackoverflow.com</a>

$ 1 = href =“www.stackoverflow.com”

$ 2 =转到stackoverflow.com

我回答了一个类似的问题,除了标签here

之外的所有内容

答案 3 :(得分:0)

正则表达式,黑魔法,再次:)

我找到一个关于普通正则表达式的nice question。有一些有趣的链接,你会发现像你这样的非常常见的regexpressions。

  

抓取HTML标签

     

&LT; TAG \ b [^&gt;] &gt;(。?)使用RegexBuddy分析此正则表达式,匹配特定HTML标记的开始和结束对。标签之间的任何内容都会被捕获到第一个反向引用中。正则表达式中的问号使得明星变得懒惰,以确保它在第一个结束标记之前而不是在最后一个标记之前停止,就像贪婪的明星一样。这个正则表达式不能正确匹配嵌套在自身内部的标签,就像onetwoone一样。

     

&lt;([AZ] [A-Z0-9] )\ b [^>] &gt;(。*?)使用RegexBuddy分析此正则表达式将匹配开启和关闭对任何HTML标记。务必关闭区分大小写。此解决方案的关键是在正则表达式中使用反向引用\ 1。标签之间的任何内容都被捕获到第二个反向引用中。此解决方案也不会匹配嵌套在其自身中的标记。

否则:浏览此链接:keyword "link"。有一些有趣的方法来过滤链接。

我希望这会有所帮助:)

祝你好运!

答案 4 :(得分:0)

嗯..使用正则表达式并不完美,但在perl regexp中,

m!<a .*?>(.*?)</a>!i

应该为您提供匹配组1中该行第一个链接的名称,忽略大小写。

限制:

  • 不在一行处理多个链接
  • 不处理多行的链接。
  • 也会在锚标签上匹配。

您可以通过将所有行连接成一行,然后使用链接start作为分隔符将其拆分为数组(或多行)来解决此问题。

答案 5 :(得分:0)

使用preg_match_all创建两者之间列表的最佳和最快捷方式。

示例:

$pattern = '#<a[^>]*>([^<]*)<\/a>#';
$subject = '<a href="#">Link 1</a> <a href="#">Link 3</a> <a href="#">Link 3</a>';
preg_match_all($pattern, $subject, $matches);
print_r($matches[1]);

结果将是:

Array (
 [0] => Link 1
 [1] => Link 3
 [2] => Link 3
)

答案 6 :(得分:0)

使用模式

'<a.*?>(.*?)</a>'

你会得到

['sign up', 'log in', 'careers 2.0']

在此标记中搜索:

<span id="hlinks-nav"><a href="/users/login?returnurl=%2fquestions%2f343115%2fregexp-for-finding-everything-between-a-and-a-tags">sign up</a><span class="lsep">|</span><a href="/users/login?returnurl=%2fquestions%2f343115%2fregexp-for-finding-everything-between-a-and-a-tags">log in</a><span class="lsep">|</span><a href="http://careers.stackoverflow.com">careers 2.0</a><span class="lsep">|</span></span>

答案 7 :(得分:0)

如果存在一些虚构的或无效的边缘情况,则带有["']i标志且边界为s的表达式也将是一个选项,例如: / p>

<a\s.*?['"]\s*>((?:(?!<\/a>).)*)<\/a>

测试

$re = '/<a\s.*?[\'"]\s*>((?:(?!<\/a>).)*)<\/a>/si';
$str = '<a href="https://google.com"
title="some title"
data-key="{\'key\':\'adf0a8dfq<>*1$4%\' >

some context in here <>

some context in there <>

</a>

<A href="https://google.com"
title="some title"
data-key="{\'key\':\'adf0a8dfq<>*1$4%\'>

some context in here

some context in there

</A>';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

var_dump($matches);

如果您希望简化/修改/探索表达式,请在regex101.com的右上角进行说明。如果愿意,您还可以在this link中查看它如何与某些示例输入匹配。


RegEx电路

jex.im可视化正则表达式:

enter image description here

答案 8 :(得分:0)

如果我要抱怨所有的正则表达式解决方案,我想我需要实际演示如何使用适当的HTML解析器(OP并没有表明要解析的HTML在任何方面都是无效的-因此合法的解析器绝对适合脚本的稳定性和质量。

现在,我的建议确实要求您熟悉DOMDocument(以及可选的DOMXPath)的基础知识,但是一旦您了解所涉及的组件,您就会发现该语法比正则表达式的含义要少得多。出于这个原因,我还将争辩说,这种技术将提高脚本的整体可读性(对于您和您的代码的未来读者而言)。

代码:(Demos

$html = <<<HTML
<a href="#">hello</a> <abbr href="#">FYI</abbr> <a title="goodbye">later</a>
<a href=https://example.com>no quoted attributes</a>
<A href="https://example.com"
title="some title"
data-key="{\'key\':\'adf0a8dfq<>*1$4%\'">a link with data attribute</A>
and
this is <a title="hello">not a hyperlink</a> but simply an anchor tag
HTML;

$dom = new DOMDocument; 
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$linkText = [];
foreach ($xpath->evaluate("//a[@href]") as $node) {
    $linkText[] = $node->nodeValue;
}
var_export($linkText);

输出:

array (
  0 => 'hello',
  1 => 'no quoted attributes',
  2 => 'a link with data attribute',
)    

如果您不关心现有的href属性:

代码:

$doc = new DOMDocument();
$doc->loadHTML($html);
$aTags = [];
foreach ($doc->getElementsByTagName('a') as $a) {
    $aTags[] = $a->nodeValue;
}
var_export($aTags);

输出:

array (
  0 => 'hello',
  1 => 'later',
  2 => 'no quoted attributes',
  3 => 'a link with data attribute',
  4 => 'not a hyperlink',
)