一个真正完整的解决方案需要更多的工作,但这里有一个镜头(注意,@
前缀假设):
^@(([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 –