\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i
| 片段 | 含義 | 說明 |
|---|---|---|
\b | 單詞邊界 | 確保 URL 前是空格、標點或字串開頭,避免匹配 abchttps://... 中的片段 |
(?:(?:https?|ftp):\/\/|www\.) | 非捕獲組:協議或 www 開頭 | https? 匹配 http/https;ftp 匹配 ftp;|www\. 允許無協議直接以 www 開頭 |
[-a-z0-9+&@#\/%?=~_|!:,.;]* | URL 主體字符集(0 次或多次) | 字符類:- 連字符(首位不需轉義)、a-z 字母、0-9 數字、+&@#/%=~_|!:,.; 常見 URL 符號。* 表示重複 0 次或多次 |
[-a-z0-9+&@#\/%=~_|] | URL 結尾字符集(至少 1 次) | 確保 URL 不以 .、,、; 等標點結尾,提高精度 |
/i | 修飾符:忽略大小寫 | 使 a-z 同時匹配大寫字母 |
-a 中的 - 是什麼?在字符類 [] 內部,- 位於**首位或末位**時代表字面連字符「-」,不需轉義。若在中間(如 a-z)則表示範圍。
&@#\/%?=~_|!:,.; 為何不轉義?在字符類 [] 內部,大多數特殊字符(含 . * + ? ^ $ ( ) { } [ ] | \)失去特殊含義,僅作字面匹配。**僅需轉義**:](結束符)、\(轉義符)、^(首位表示取反)、-(中間表示範圍)。此處 / 雖轉義但非必須。
[]?* 不夠嗎?* 允許 0 次匹配,會導致 https:// 也匹配成功(空主體)。結尾 [] 要求**至少一個合法結尾字符**,強制 URL 有實質內容。建議將前面 * 改為 +(至少一次),邏輯更清晰。
/i 是什麼?正則修飾符(Flag),表示**大小寫不敏感**。JavaScript 寫法 /pattern/i,Java/Python 用 Pattern.CASE_INSENSITIVE / re.IGNORECASE。
\b(?:https?|ftp)://[^\s/$.?#].[^\s]*
[^\s/$.?#]:首字符非空白/保留字符.[^\s]*:後續任意非空白字符// JavaScript
const urlRegex = /\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i;
console.log(urlRegex.test('https://example.com/path?query=1')); // true
console.log(urlRegex.test('www.google.com')); // true
console.log(urlRegex.test('https://')); // false (結尾字符類要求)
// Java
Pattern pattern = Pattern.compile("\\b(?:(?:https?|ftp):\\/\\/|www\\.)[-a-z0-9+&@#\\/%?=~_|!:,.;]*[-a-z0-9+&@#\\/%=~_|]", Pattern.CASE_INSENSITIVE);
理解正則各元件含義,可根據業務靈活調整(如支援 IP、端口、路徑深度限制等),避免盲目複製導致誤匹配/漏匹配。