Regex删除到另一个域的链接


Regex Remove link to another domain

我收到一个格式化为html的文本。我想限制锚标记的url只能来自我的域,用"xxx"(或smth'else)替换旧链接
输入:"<a href='otherdomain'>text</a>"
输出:"xxx"
我正在使用regexp来实现这一点,尽管我有点拘泥于此:

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

这里怎么了?

当您执行[^mydomain.*'"'']时,您会说"匹配除文字'm'、'y'、'd'、'o'、…、'.'、'*'等之外的任何字符。

试试类似的东西:

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

注:

  • 我将您的a.*href转换为a [^>]*'bhref,以确保"a"answers"href"是完整的单词,并且正则表达式在多个标记上不匹配
  • 我将正则表达式分隔符改为"#"而不是"/",这样您就不必再转义/
  • 注意((?!mydomain)[^'"])+。这意味着"match[^'"]+不是mydomain。(?!被称为负前瞻
  • 注意'1。这样可以确保URL的结束引号与开始引号相同(请参阅第一组括号如何捕获['"]?)。如果你愿意的话,没有它你可能会没事的

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

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

在这里看到它的实际操作,在那里你可以根据自己的目的进行调整。

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

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;    
    }
}

(尽管这不是不解释的理由。)

如果你想匹配"除之外的任何东西",那么你通常需要使用断言;在你的案例中,一个负面的前瞻性断言:

 (?!mydomain'.com).*?

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

还要注意:

  • 它应该是['"'']而不是[''|'"]。替代符号在字符类中没有意义
  • CCD_ 13通常应该是CCD_
  • [^>]*是在标签中进行匹配的常见习惯用法
  • 您可以使用其他分隔符#<a...*>#i来代替/以避免转义

[]是集合运算符中的字符。作为,你的模式会更容易理解

$pattern ='!<a's.*?'shref's*='s*([''"])https?:://mydomain.*?'1.*?</a>!is';

注:

  • 我用空格分隔了标记
  • 交换了regexp引用的char以避免'/
  • 使用反向引用来匹配引号