正则表达式删除到另一个域的链接

时间:2012-02-12 12:06:33

标签: php regex

我收到格式为html的文本。我想限制锚标记的网址只能从我的域名替换旧链接“xxx”(或smth'其他)。
输入:“<a href='otherdomain'>text</a>
输出:“xxx”
我正在使用正则表达式实现这一点,虽然我有点困在这里:

$pattern ='/<a.*href=[\'|\"]http.?:\/\/[^mydomain.*\"\']*[\'|\"].*<\/a>/i';
$replace ='xxx';
echo preg_replace($pattern, $replace, $string); 

这里有什么问题?

4 个答案:

答案 0 :(得分:2)

当你执行[^mydomain.*\"\']时,你说“匹配任何字符,除了字面'm','y','d','o',...,'。','*'等

尝试类似:

#<a [^>]*\bhref=(['"])http.?://((?!mydomain)[^'"])+\1 *>.*?</a>#i

注意:

  • 我将您的a.*href转为a [^>]*\bhref,以确保'a'和'href'是完整的单词,并且正则表达式与多个标签不匹配。
  • 我将正则表达式分隔符更改为“#”而不是“/”,因此您不必再逃避/
  • 请注意((?!mydomain)[^'"])+。这意味着“匹配[^'”] +不是mydomain“。(?!被称为负面预测
  • 请注意\1。这可以确保URL的结束引号与开始引号相同(请参阅第一组括号捕获['"]?)。如果你愿意的话,没有它你可能没问题。

对于PHP(更新,因为我总是在需要在PHP中转义反斜杠时混淆 - 请参阅下面的@ GlitchMr评论):

$pattern = '#<a [^>]*\bhref=([\'"])http.?://((?!mydomain)[^\'"])+\1 *>.*?</a>#i';

在行动here中查看,您可以根据自己的需要进行调整。

答案 1 :(得分:2)

这是我正在使用的代码的一部分。它正在使用用户函数来更改正则表达式挖出的文本。祝你好运:)

class RedirectLinks {
    /**
     * Callback used by convert_external_links_to_internal on each url found
     *
     * @param array $matches
     * @return string
     */
    public static function urlMatchCallback($matches)
    {
        if (stripos($matches[1], 'http://') === false ||
            stripos($matches[1], 'example.com') !== false
            ) {
            return $matches[0]; // do not modify
        }
        // encrypt url for redirection          
        $sURL = $matches[1];
        return "href=\"#\" onclick=\"showmessage('$sURL');\"";
    }

    /**
     * Converts external links in text to internal ones
     *
     * @param string $str - text
     * @return the processed text
     */
    public static function convertExternalLinksToInternal($str) {
        // convert external links to internal redirections
        $str = preg_replace_callback("/href=\"([^\"]*)\"/is", 'RedirectLinks::urlMatchCallback', $str);

        return $str;    
    }
}

答案 2 :(得分:1)

(虽然没有理由不解释某事。)

如果你想匹配'除了'之外的任何东西,那么你通常想要使用一个断言;在你的情况下negative lookahead assertion

 (?!mydomain\.com).*?

这将匹配.*?任何内容,但是在它之前的不允许值。

另请注意:

  • 应该是[\"\']而不是[\'|\"]。替代标志在字符类中没有意义。
  • .*通常应该.*?不能过于宽泛地匹配。
  • [^>]*是标记内匹配的常用习惯用法。
  • 您可以使用其他分隔符#<a...*>#i代替/以避免转义。

答案 3 :(得分:0)

[]是字符集合运算符。

,你的模式会更容易理解
$pattern ='!<a\s.*?\shref\s*=\s*([\'"])https?:://mydomain.*?\1.*?</a>!is';

注意:

  • 我用空格分隔了令牌
  • 交换了正则表达式引用字符以避免\/
  • 使用后引用匹配引号。