grep有效域正则表达式

Ark*_*rka 6 regex dns bash grep

我正在尝试为只匹配有效域的grep创建一个正则表达式.

我的版本工作得很好,但匹配以下无效域:

@subdom..dom.ext
Run Code Online (Sandbox Code Playgroud)

这是我的正则表达式:

echo "@dom.ext" | grep "^@[[:alnum:]]\+[[:alnum:]\-\.]\+[[:alnum:]]\+\.[[:alpha:]]\+\$"
Run Code Online (Sandbox Code Playgroud)

我正在使用bash,所以我逃脱了特殊字符.

应匹配的示例:

@subdom.dom.ext
@subsubdom.subdom.dom.ext
@subsub-dom.sub-dom.ext
Run Code Online (Sandbox Code Playgroud)

感谢帮助

mkl*_*nt0 8

一个真正完整的解决方案需要更多的工作,但这里有一个可能运行良好近似值(注意@假设前缀,输入字符串应该从它开始):

^@(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$
Run Code Online (Sandbox Code Playgroud)

您可以将此与egrep(或grep -E),以及[[ ... =~ ... ]]bash的正则表达式匹配运算符一起使用.

进行以下假设,这些假设比实际DNS名称约束更宽松:

  • 只允许使用ASCII(非外国)字母 - 请参阅下面的国际化域名(IDN)注意事项; 此外,Punycode*(ASCII兼容)形式的IDN - 例如,xn--bcher-kva.ch用于bücher.ch- 不匹配 - 见下文.

  • 嵌套子域的数量没有限制.

  • 对任何标签(名称组件)的长度没有限制,并且对名称的总长度没有限制(对于实际限制,请参见此处).

  • TLD(最后一个组件)仅由字母组成,长度至少为2.

  • 子域名和域名都必须以字母开头; 子域名允许为单个字母.

这是一个快速测试:

for d in @subdom..dom.ext @dom.ext @subdom.dom.ext @subsubdom.subdom.dom.ext @subsub-dom.sub-dom.ext @x.org; do
 [[ $d =~ \
    ^@(([a-zA-Z](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ \
 ]] && echo YES || echo NO
done
Run Code Online (Sandbox Code Playgroud)

支持带有文字 Unicode字符的国际化域名(IDN) - 同样,完整的解决方案需要更多工作:

一个简单的改进,也匹配IDN的是取代[a-zA-Z][[:alpha:]][a-zA-Z0-9][[:alnum:]]在上述的正则表达式; 即:

^@(([[:alpha:]](-?[[:alnum:]])*)\.)+[[:alpha:]]{2,}$
Run Code Online (Sandbox Code Playgroud)

警告:

  • 没有尝试识别使用带有前缀的基于ASCII的编码的IDN的Punycode编码版本xn--,并且之后需要解码.

  • 正如Patrick Mevzek指出的那样,上面可以产生假阴性和假阳性(使用他的例子):

    • 误报:无效的 Punycode编码名称,如ab--whatever
    • 误报:无效的跨语言名称; 例如,c?fe.fr它使用法语域名中的希腊字母 - 这是一个单独使用正则表达式无法执行的规则.
    • 假阴性:基于表情符号的名称,如.ws(xn--jr8h.ws)
    • 假阴性:???????今天是IANA根目录中的有效TLD,但不匹配[[:alpha:]]{2,}$
    • ... 还有很多
  • 当与[[:alpha:]]或匹配时,并非所有类Unix平台都完全支持所有Unicode字母[[:alnum:]].例如,使用基于UTF-8的语言环境,OS X 10.9.1显然只匹配拉丁语变音符号(例如ü,á)和西里尔字符(除ASCII之外),而Linux 3.2似乎可以覆盖所有脚本,包括亚洲语和阿拉伯语那些.

  • 我不清楚从右到左书写脚本中的名称是否正确匹配.

  • 为了完整起见:即使上面的正则表达式没有尝试强制执行长度限制,尝试使用IDN也会更加复杂,因为长度限制适用于名称的ASCII编码(通过Punycode),而不是原版的.

对@Alfe的提示以及指出IDN问题的提示,以及@Arka提供正则表达式的简化版本以替换我最初根据错误假设必须统治单字母域名而制作的较长版本出.