【问题标题】:Regex PHP, Match all links with specific text正则表达式 PHP,将所有链接与特定文本匹配
【发布时间】:2010-12-12 06:47:01
【问题描述】:

我正在寻找 PHP 中的正则表达式,它将锚点与特定文本匹配。例如,我想获得带有 mylink 文本的锚点,例如:

<a href="blabla" ... >mylink</a>

所以它应该匹配所有的锚,但前提是它们包含特定的文本所以它应该匹配这些字符串:

<a href="blabla" ... >mylink</a>

<a href="blabla" ... >blabla mylink</a>

<a href="blabla" ... >mylink bla bla</a>

<a href="blabla" ... >bla bla mylink bla bla</a>

但不是这个:

<a href="blabla" ... >bla bla bla bla</a>

因为这个不包含单词mylink。

这个也不应该匹配:"mylink is string",因为它不是锚。

有人有什么想法吗?

感谢花岗岩

【问题讨论】:

标签: php regex pattern-matching html-parsing


【解决方案1】:

这应该可以工作(构建正则表达式字符串并插入您需要的任何字符串而不是“mylink”)

<\s*a\s+[^>]*>[^<>]*mylink[^<>]*<\s*\/a\s*>

但不建议这样做。您应该改用 HTML 解析器并处理标签。正则表达式并不是真正合适的工具。 (如果您有包含“>”的链接,上述正则表达式将不起作用,尽管这可能很少见)

如果你只使用适当的环绕,我认为 php 不需要任何特殊的转义字符。

在 regexpal.com 测试

一些注意事项::
\s* - 匹配可选空格
\s+ - 匹配至少一个空格/制表符和任何额外的可选空格
[^>] - 匹配除 '>' 以外的任何字符
[^]- 匹配除 ''

之外的任何字符

更新:为与 m/regex/ 匹配的 php 转义了“/”

【讨论】:

  • 请注意,一个属性值可以包含一个普通的&gt;
  • 当然,添加了免责声明。我可以继续添加 href="[^"]*"|'[^']' 但接下来您希望所有属性都允许 > 然后我必须允许属性名称仅以字符而不是数字开头. 这就是我说使用 HTML 解析器的原因。:D
  • 我收到警告:警告:preg_match(): Unknown modifier 'a'
  • @Granit,您要么需要在正则表达式中转义 /,要么使用不同的分隔符。但说真的,我的建议有什么问题?
  • @Granit:使用 HTML 解析器。总有一天会更好。使用现有的基于 sax 的解析器来捕获 a 标签,并且应该这样做。简单整洁。 +1 巴特
【解决方案2】:

尝试使用解析器:

require_once "simple_html_dom.php";

$data = 'Hi, I am looking for a regular expression in PHP which would match the anchor with a 
specific text on it. E.g I would like to get anchors with text mylink like: 
<a href="blabla" ... >mylink</a>

So it should match all anchors but only if they contain specific text So it should match t
hese string:

<a href="blabla" ... >mylink</a>

<a href="blabla" ... >blabla mylink</a>

<a href="blabla" ... >mylink bla bla</a>

<a href="blabla" ... >bla bla mylink bla bla</a>

but not this one:

<a href="blabla" ... >bla bla bla bla</a> Because this one does not contain word mylink.

Also this one should not match: "mylink is string" because it is not an anchor.

Anybody any Idea? Thanx Granit';

$html = str_get_html($data);

foreach($html->find('a') as $element) {
  if(strpos($element->innertext, 'mylink') === false) {
    echo 'Ignored: ' . $element->innertext . "\n";
  } else {
    echo 'Matched: ' . $element->innertext . "\n";
  }
}

产生输出:

Matched: mylink
Matched: mylink
Matched: blabla mylink
Matched: mylink bla bla
Matched: bla bla mylink bla bla
Ignored: bla bla bla bla

http://simplehtmldom.sourceforge.net/下载simple_html_dom.php

【讨论】:

    【解决方案3】:
    /<a[^>]*>([^<]*mylink[^<]*)<\/a>/
    

    这有点简单,因为如果标签位于链接内 (&lt;a href="/xyz"&gt;xyz &lt;i&gt;mylink&lt;/i&gt; aaa&lt;/a&gt;),它会中断,但它应该可以工作。

    【讨论】:

    • 请注意,一个属性值可以包含一个普通的&gt;
    【解决方案4】:
    if (preg_match('%<\s*a\s+href="blabla"[^>]*>(.*mylink.*)<\s*/a>%', $text, $regs)) {
        $result = $regs[1];
    } else {
        $result = "";
    }
    

    $regs[0] 将举行完整的比赛 $regs[1] 将保留 a 标签内的位

    【讨论】:

    • 请注意,一个属性值可以包含一个普通的&gt;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 2011-05-13
    相关资源
    最近更新 更多