我正在编写一个正则表达式模式,它将排除两个模式,以便在页面上创建可点击链接;
$message = preg_replace("#(((f|ht)tp(s)?://)(?!img.youtube.com/vi/)[-a-zA-Z?-??-?()0-9@:%_+.~\#?&;//=,]+)#i", "<a href=$1 target='_blank'><b>$1</b></a>", $message);
第一个模式(?!img.youtube.com/vi/)似乎工作正常 - 如果在$ message中找到此模式,它会跳过它。第二种模式我遇到了麻烦。我不希望这个正则表达式适用于带有.jpg,.gif和.bmp扩展名的模式(所以,http://dfjrnen.com/fjejfj.jpg。我有另一个正则表达式处理这些类型的字符串,并希望上面的那个不影响它
所以,似乎如果我想这样做,我应该像这样设置一些东西;
$message = preg_replace("#(((f|ht)tp(s)?://)(?!img.youtube.com/vi/)[-a-zA-Z?-??-?()0-9@:%_+.~\#?&;//=,]?!(\.jpg|\.gif|\.bmp)+)#i", "<a href=$1 target='_blank'><b>$1</b></a>", $message);
这似乎不起作用。有人可以指出这个问题吗?
答案 0 :(得分:1)
$legal = '-a-zA-Z()0-9@:%_+.~\#?&;/=,';
$regex = "#((f|ht)tps?://(?!img.youtube.com/vi/)[$legal]+)" .
"(?<!\.jpg|\.gif|\.bmp)(?<!\.jpeg)(?![$legal])#i";
$replace = "<a href=$1 target='_blank'><b>$1</b></a>";
$message = preg_replace($regex, $replace, $message);
$legal
中,因为它们在模式中需要两次,我们不想将它们重复写入。(?<!...)
。我使用两个独立的lookbehinds来扩展不同的长度 - 否则PHP会抱怨:preg_replace(): Compilation failed: lookbehind assertion is not fixed length
http://dfjrnen.com/fjejfj.jpg
,匹配将是http://dfjrnen.com/fjejfj.jp
。要在这种情况下排除整个匹配,我们可以使用否定前瞻 (?![$legal])
检查以下字符是否确实不属于网址。