簡體   English   中英

如何解決此preg_replace代碼?

[英]How to fix this preg_replace codes?

具有以下代碼將消息中的URL轉換為HTML鏈接:

$message = preg_replace("#(http|https|ftp|ftps)://([.]?[&;%=a-zA-Z0-9_/?-])*#",
    "<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);

$message = preg_replace("#(^| |\n)(www([.]?[&;%=a-zA-Z0-9_/?-])*)#",
    "\\1<a href=\"away?to=http://\\2\" target=\"_blank\">\\2</a>", $message);

除以下情況外,它幾乎對所有鏈接都非常有效:

1) http://example.com/mediathek#/video/1976914/zoom:-World-Wide

這里的問題是鏈接中的#: ,因為沒有轉換完整的鏈接。

2) If someone just writes "www" in a message

例如: <a href="http://www">www</a>

因此,問題在於上面的代碼中是否有辦法解決這兩種情況

由於要在正則表達式中包含井號# ),因此需要將定界符更改為不包含在正則表達式中的字符,例如! 因此,您的正則表達式應如下所示:

$message = preg_replace("!(http|https|ftp|ftps)://([.]?[&;%#:=a-zA-Z0-9_/?-])*!",
"<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);

這有幫助嗎?

但是,如果您想更進一步了解規范( RCF 1738 ),則可能要排除URL中不允許的% 還有一些您未包括的允許的字符:

  • $
  • _
  • (點)
  • +
  • *

如果要包含這些字符,則應使用%分隔正則表達式。

幾個小調整。 在第一個正則表達式中添加\\#: ,然后在第二個正則表達式中將*更改為+

$message = preg_replace("#(http|https|ftp|ftps)://([.]?[&;%=a-zA-Z0-9_/?\#:-])*#",
    "<a href=\"away?to=\\0\" target=\"_blank\">\\0</a>", $message);

$message = preg_replace("#(^| |\n)(www([.]?[&;%=a-zA-Z0-9_/?-])+)#",
    "\\1<a href=\"away?to=http://\\2\" target=\"_blank\">\\2</a>", $message);

我認為解決這個問題是徒勞的。 and then test it with FILTER_VALIDATE_URL. 一個很好的選擇是通過正則表達式查找URL ,然后使用FILTER_VALIDATE_URL對其進行測試。 請記住,此過濾器不是PHP手冊所述的防水方式:

"Note that the function will only find ASCII URLs to be valid; internationalized domain names (containing non-ASCII characters) will fail."

代碼示例(未經測試):

$message = preg_replace_callback(
    '~(?(DEFINE)
          (?<prot> (?>ht|f) tps?+ :// )         # you can add protocols here
      )
      (?>
          <a\b (?> [^<]++ | < (?!/a>) )++ </a>  # avoid links inside "a" tags
        |
          <[^>]++>                              # and tags attributes.
      ) (*SKIP)(?!)                             # makes fail the subpattern.
      |                                         # OR
      \b(?>(\g<prot>)|www\.)(\S++)              # something that begins with
                                                # "http://" or "www."
     ~xi',
    function ($match) {
        if (filter_var($match[2], FILTER_VALIDATE_URL)) {
            $url = (empty($match[1])) ? 'http://' : '';
            $url .= $match[0];
            return '<a href="away?to=' . $url . '"target="_blank">'
                 . $url . '</a>';
        } else { return $match[0] }
    },
    $message);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM