2013-03-07 79 views
1

我想創建一個腳本,將新的域添加到我們的DNS服務器。我發現 REGEL。 然而,當我與SED使用它,它不工作,我所期望的:基於Bash的正則表達式域名驗證

echo test | sed '/(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(:[a-zA-Z]{2,})$)/p' 
-------- 
Output is: 
test 
echo test.com | sed '/(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(:[a-zA-Z]{2,})$)/p' 
-------- 
Output is: 
test.com 

我預計第一個命令的輸出應該是一個空行。 我做錯了什麼?

+0

它根本不符合你的字符串。嘗試'sed -n'確認。 – anishsane 2013-03-07 10:53:38

回答

2

你缺少一個問號在您正則表達式:

(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(:[a-zA-Z]{2,})$)

您可以測試你的正則表達式here

你可以做你想要使用grep什麼:

$ echo test.com | grep -P '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)' 
test.com 
$ echo test | grep -P '(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+(?:[a-zA-Z]{2,})$)' 
$ 
+0

如果我測試了test.-com,它會通過。這是無效的,對嗎? – Dennis 2016-06-10 23:35:16

+0

沒有爲我工作..嘗試自己例如:'echo fireb | grep -P'(?= ^。{5,254} $)(^(?:(?!\ d + \。)[a-zA-Z0-9 _ \ - ] {1,63} \。?)+(? :[A-ZA-Z] {2,})$)''。它會返回:fireb。但它不是一個域名。另一個例子:'echo berif_novp | grep -P'(?= ^。{5,254} $)(^(?:(?!\ d + \。)[a-zA-Z0-9 _ \ - ] {1,63} \。?)+(? :[A-ZA-Z] {2,})$)''。返回:berif_novp,但這不是一個域。即使嘗試在rubular.com上,它也是匹配不是域的字符串。** – 2017-05-07 03:33:45

0

皮埃爾 - 路易斯的回答也不太爲我工作。例如「小貓」被認爲是一個域名。 我加了一個小小的調整,以確保域至少有一個點。

(?=^.{5,254}$)(^(?:(?!\d+\.)[a-zA-Z0-9_\-]{1,63}\.?)+\.(?:[a-z]{2,})$) 

在它讀取域的最後部分之前,額外的\.

+0

不應該是實際開始的'(?= ^。{4,254} $)'? 「t.co」是一個有效的域名(目前正在使用!),只有4個字符長... – 2014-11-10 17:09:49

+0

「修復」不正確。虛假點現在允許TLD之前的兩個連續的點。更好的解決方法是在已經存在的字面點之後移除問號(但在技術上不正確;例如'dk'本身就是有效的域名)。 – tripleee 2015-02-17 13:02:50

6

我覺得這是一個比較全面的正則表達式:

(?=^.{4,253}$)(^(?:[a-zA-Z](?:(?:[a-zA-Z0-9\-]){,61}[a-zA-Z])?\.)+[a-zA-Z]{2,}$)

  • RFC 1034§3:允許爲4-25 的長度,用我所知道的最短的作戰領域,「 t.co「,仍然與其他答案不匹配的地方相匹配。 255個字節的最大長度,減去每個標籤的長度八位字節(TLD和「主」子域)爲我們提供了253:(?=^.{4,253}$)
    • RFC 3696§2:單字母的TLD 技術上允許的,這意味着最小長度將是3 ,但由於目前沒有單字母TLD,因此最小長度爲4是可行的。
  • RFC 1034§3:在子域允許數字,康納爾Clafferty的顯然不(通過不從「初級」的子域區別其他子域 - 即你註冊的域名 - 其DNS規範沒有)
  • RFC 1034§3:限制單個標籤63個字符,從而允許連字符在中間,同時限制的開始和結束,以字母數字(?:[a-zA-Z0-9](?:(?:[a-zA-Z0-9\-]){,61}[a-zA-Z0-9])?\.)
  • 需要兩個字母或更大的TLD [a-zA-Z]{2,}
    • RFC 3696§2:該DNS規格噸在技​​術上允許頂級域名(TLD)中的數字以及單字母頂級域名(TLD);不過,目前還沒有單字母頂級域名(TLD)或頂級域名(TLD),並且不允許使用全數字頂級域名(TLD),因此這部分正則表達式已經被簡化。
+2

謝謝你如此精確,解釋你自己,並援引消息來源。有助於做出快速,明智的選擇。 – 2015-03-23 13:41:01

+1

對我來說就像一個魅力工作..我也編寫了一個名爲isdom的bash函數,所以我可以用'isdom string'來調用它,它根據這個regexp響應yes/no。 – 2017-05-07 03:28:00

0

沒有sed實現我知道支持你正在使用該正則表達式的各種Perl擴展。嘗試使用Perl或grep -Ppcregrep,或將正則表達式簡化爲sed可應對的內容。這是一個快速和骯髒的適應,將正則表達式分解爲三個不同正則表達式的腳本,並在某些事情不匹配時拒絕(或匹配,在中間情況下)。

echo 'test' | sed -r '/^.{5,254}$/!d 
    /^([^.]*\.)*[0-9]+\./d # Seems incorrect; 112.com is valid 
    /^([a-zA-Z0-9_\-]{1,63}\.?)+([a-zA-Z]{2,})$/!d' # should disallow underscore 
    # also, what's with the question mark after the literal dot? 

這也完全不能接受IDNA域(它可以包含在TLD破折號和號碼,除其他事項外),所以我絕對不會推薦這一點,但希望它展示瞭如何像這樣適應sed如果你願意。

0

我用grep -P來做到這一點。

echo test | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$" 
-------- 
Output is: 

echo www.test.com | grep -P "^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$" 
-------- 
Output is: www.test.com