在正则表达式中省略模式

时间:2014-05-10 00:59:33

标签: php regex

我正在编写一个正则表达式模式,它将排除两个模式,以便在页面上创建可点击链接;

$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);

这似乎不起作用。有人可以指出这个问题吗?

1 个答案:

答案 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])检查以下字符是否确实不属于网址。