我收到一个格式化为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以避免
'/
- 使用反向引用来匹配引号