一個真正完整的解決方案需要更多的工作,但這裏有一個鏡頭(注意,@
前綴假設):
^@(([a-zA-Z](-?[a-zA-Z0-9])*)\.)*[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}$
你可以用egrep
(或grep -E
)使用,也可與[[ ... =~ ... ]]
,bash的正則表達式匹配運算符。
做以下假設,它比實際的DNS名稱的限制更寬鬆:
- 只有ASCII(非外資)字母被允許 - 請參閱下面的國際化域名(IDN)的考慮;還有,IDN的ASCII形式 - 例如
xn--bcher-kva.ch
(bücher.ch
) - 不匹配(儘管它很容易解決)。
- 對嵌套子域的數量沒有限制。
- 對任何標籤(名稱組件)的長度沒有限制,對名稱的總長度沒有限制(實際限制見here)。
- TLD(最後一個組件)僅由字母組成,其長度至少爲2.
- 子域和域名都必須以字母開頭;該域名的長度必須至少爲2;子域允許爲單字母。
下面是一個簡單的測試:
for d in @subdom..dom.ext @dom.ext @subdom.dom.ext @subsubdom.subdom.dom.ext @subsub-dom.sub-dom.ext; do
[[ $d =~ \
^@(([a-zA-Z](-?[a-zA-Z0-9])*)\.)*[a-zA-Z](-?[a-zA-Z0-9])+\.[a-zA-Z]{2,}$ \
]] && echo YES || echo NO
done
支持Internationalized Domain Names (IDN):
一個簡單的改進,也符合國際化域名是在[[:alnum:]]
與[[:alpha:]]
和[a-zA-Z0-9]
更換[a-zA-Z]
以上正則表達式;即:
^@(([[:alpha:]](-?[[:alnum:]])*)\.)*[[:alpha:]](-?[[:alnum:]])+\.[[:alpha:]]{2,}$
注意事項:
並非所有的類Unix平臺對[[:alpha:]]
或[[:alnum:]]
匹配時,完全支持所有的Unicode字符。例如,使用基於UTF-8的語言環境,OS X 10.9.1顯然只匹配拉丁變音符號(例如,ü
,á
)和西里爾文字符(除ASCII之外),而Linux 3.2似乎涵蓋所有腳本,包括亞洲和阿拉伯語。
我不清楚從右到左書寫腳本中的名稱是否正確匹配。
爲了完整起見:即使上述正則表達式不試圖強制執行長度的限制,試圖與國際化域名這樣做會更復雜,因爲篇幅所限適用於ASCII編碼名稱(通過Punycode),而不是原來的。
@Alfe指出IDN問題的提示。
如果有必要準確grep和比賽唯一的現有頂級域名的,看看https://stackoverflow.com/questions/14460680/how-to-get-a- list-of-tlds-using-bash-for-building-a-regex –