2013-05-18 16 views
0

我有一個是試圖檢測標題&鏈接標記正則表達式:如何限制正在檢測太多的正則表達式?

[title](http://link.com) 

到目前爲止,我有:

(\[)(.*?)(\])(\(((http[s]?)|ftp):\/\/)(.*?)(\)) 

這是檢測到多,當一個無標題的鏈接標記是之前

[http://google.com] [Digg](http://digg.com) 
[Internal Page] Random other text [Digg](http://digg.com) 

如何限制正則表達式只是標題鏈接?

完整的PHP標題爲&無鏈接:

// Titled Links 
    // [Digg](http://digg.com) 
    // [Google](http://google.com) 
    $text = preg_replace_callback(
     '/(\[)(.*?)(\])(\(((http[s]?)|ftp):\/\/)(.*?)(\))/', 
     function ($match) { 
      $link = trim($match[7]); 
      $ret = "<a target='_blank' href='" . strtolower($match[5]) . "://" . $link . "'>" . trim($match[2]) . "</a>"; 
      if (strtolower($match[5]) == "http") { 
       $ret .= "<img src='/images/link_http.png' class='link' />"; 
      } else if (strtolower($match[5]) == "https") { 
       $ret .= "<img src='/images/link_https.png' class='link' />"; 
      } else if (strtolower($match[5]) == "ftp") { 
       $ret .= "<img src='/images/link_ftp.png' class='link' />"; 
      } 
      return $ret; 
     }, 
     $text 
    ); 

    // Untitled Links 
    // [Internal Page] 
    // [http://google.com] 
    $text = preg_replace_callback(
     '/(\[)(.*?)(\])/', 
     function ($match) { 
      $link = trim($match[2]); 

      $ret = ""; 
      if ($this->startsWith(strtolower($link), "https")) { 
       $ret = "<a target='_blank' href='" . $link . "'>" . $link . "</a>"; 
       $ret .= "<img src='/images/link_https.png' class='link' />"; 
      } else if ($this->startsWith(strtolower($link), "http")) { 
       $ret = "<a target='_blank' href='" . $link . "'>" . $link . "</a>"; 
       $ret .= "<img src='/images/link_http.png' class='link' />"; 
      } else if ($this->startsWith(strtolower($link), "ftp")) { 
       $ret = "<a target='_blank' href='" . $link . "'>" . $link . "</a>"; 
       $ret .= "<img src='/images/link_ftp.png' class='link' />"; 
      } else { 
       $link = str_replace(" ", "_", $link); 
       $ret = "<a href='" . $link . "'>" . trim($match[2]) . "</a>"; 
      } 
      return $ret; 
     }, 
     $text 
    ); 
+1

這麼多括號......反正[這裏](http://regex101.com/r/hG9hM8)是我想出來的,快樂的編碼...... – HamZa

回答

0

通過附加一個使標題可選的 '?'到與標題匹配的組。

0

而不是(.*?)嘗試匹配你真正不想要的東西,如([^\s]+)

此外,整個第二部分是可選的(如果您可以有一個未命名的鏈接),所以像@Arnout建議的那樣添加?,例如,

(\(((http[s]?)|ftp):\/\/)([^\s]+)(\))? 

我還建議,(雖然我不知道它在PHP中的正則表達式it appears to be支持,使用空格標誌,打破它在幾行以便於閱讀:

/ 
    (
    \[ 
) 
    (.*?) 
    (
    \] 
) 
    (
    \(
    (
     (http[s]?) 
     | 
     ftp 
    ) 
    :\/\/ 
) 
    (.*?) 
    (
    \) 
) 
/x 

也就是說很多更清晰,更容易看到:

  • [s]?可能只是s?
  • 的計劃括號應該是((?:https?)|(?:ftp)),或者它只在f上或者,你會得到額外的不需要的捕獲。

你也許可以在正則表達式中對它進行評論(同樣,我不確定你可以使用PHP)。

0

這工作,但沒有按」沒有你想要匹配的所有組的括號。

\[[\w\s]+\]\((https?|ftp)://[^)]+\)