2011-03-04 20 views
9

我試圖驗證將用作子域的用戶輸入字符串。具體規則如下:在長度Ruby中有效子域的正則表達式

  1. 介於1到63個字符(我拿63從谷歌Chrome瀏覽器似乎允許在一個子域,不知道它實際上是一個服務器指令的字符數。如果你有更好的在有效的最大長度的建議,我感興趣的是聽到其)
  2. 可能包含A-ZA-Z0-9,連字符,下劃線
  3. 不能開始或以連字符結束或下劃線

編輯:從下面的輸入中,我添加了以下內容: 4.不應包含co連續的連字符或下劃線。

例子:

a => valid 
0 => valid 
- => not valid 
_ => not valid 
a- => not valid 
-a => not valid 
a_ => not valid 
_a => not valid 
aa => valid 
aaa => valid 
a-a-a => valid 
0-a => valid 
a&a => not valid 
a-_0 => not valid 
a--a => not valid 
aaa- => not valid 

我的問題是我不知道如何指定與該字符串允許只有一個字符一個正則表達式,同時還規定,它可能無法開始或結尾的連字符或下劃線。

謝謝!

+1

http://stackoverflow.com/questions/4551963/regex-help-subdomain-check – Orbit 2011-03-04 16:41:28

+0

謝謝,鏈接的主題包括一個完整的域有效性檢查,我只是在尋找一個字符串有效的使用一個子域。你有建議如何修改它的工作?我似乎無法做出必要的更改。 – gsr 2011-03-04 16:53:16

回答

17

不能可以在下有下劃線正確的子域名,但是你需要它們嗎? trim明輸入之後,做一個簡單的字符串長度檢查,然後用這個測試:

/^[a-z\d]+(-[a-z\d]+)*$/i 

通過上述,您將無法獲得連續的-字符,例如a-bbb-ccc通行證和a--d失敗。

/^[a-z\d]+([-_][a-z\d]+)*$/i 

也會允許不連續的下劃線。


更新:,你會發現,在實踐中,下劃線是不允許的,所有子域名必須以字母開頭。上述解決方案不允許國際化子域名(punycode)。你想利用這個

/\A([a-z][a-z\d]*(-[a-z\d]+)*|xn--[\-a-z\d]+)\z/i 
+0

考慮後,我同意允許連續的連字符和下劃線會造成非常醜陋的子域。欣賞輸入。這很好。 – gsr 2011-03-04 17:22:54

+0

我正在考慮更嚴格的域名,但我不打擾像選定的答案一樣的連續分隔符,它們看起來很醜,並且不會增加可用性/可讀性。 – Walf 2011-03-04 17:24:03

+0

這個正則表達式是我需要的,但是如何強制最小字符長度爲完整的字符串。在{n,}在不同的地方嘗試了不同的設置,但沒有任何工作。 – webdeb 2015-10-19 11:31:51

-1

/[^\W\_](.+?)[^\W\_]$/i應該爲ya工作(試試http://rubular.com/來測試正則表達式)

編輯:實際上,這不檢查單/雙字母/數字。嘗試/([^\W\_](.+?)[^\W\_])|([a-z0-9]{1,2})/i,而不是在rubular中修改它,直到你得到你想要的東西(如果這已經沒有照顧它)。

+0

謝謝,我一直在使用rubular,它是一個很棒的測試工具。我認爲你給出的表達方式與我一直不允許少於3個字符的字符串相同。此外,它似乎允許中間的連字符和下劃線以外的字符(a&a有效)。我也想知道你是否有意將這個^從頭開始,如果是的話,是出於什麼原因。 – gsr 2011-03-04 16:51:11

+1

與'.nNGygyG(NG(NG966%&i.')相匹配,並且也會與其他許多垃圾匹配。你需要閱讀正則表達式.PHP手冊的PCRE部分非常有用。 – Walf 2011-03-04 17:04:06

+0

Thanks @Lucas,我​​確實忘記了在重複匹配中包含零個匹配字符忽略我的建議:) – William 2011-03-07 14:21:15

0
/^([a-z0-9][a-z0-9\-\_]{0,61}[a-z0-9]|[a-z0-9])$/i 

我已經把它當成一個挑戰,創造一個正則表達式應該只匹配與不重複的連字符或下劃線的字符串,並檢查你的適當長度:

/^([a-z0-9]([_\-](?![_\-])|[a-z0-9]){0,61}[a-z0-9]|[a-z0-9])$/i 

中間部分使用一個lookaround來驗證。

+0

原始文件也應該用於2個字母的條目(這就是爲什麼存在'{0,61}''也可以省略問號,我會編輯它 – 2011-03-04 17:02:39

+0

現在工作很好,謝謝! – gsr 2011-03-04 17:10:19

+0

這將匹配'a ___ --- _____ - __ - __ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _什麼在最後'和'無論在開始^ &* ^&^)^)_ --- _-- abc'。如果你堅持允許使用'-'和'_'填充可怕的子域名,那麼你需要在括號中加上括號:'/ ^([a-zA-Z0-9] [a-zA-Z0-9 \ - \ _] {0,61}?[a-zA-Z0-9] | [a-zA-Z0-9])$ /' – Walf 2011-03-04 17:11:27

0

我不熟悉Ruby的正則表達式語法的更好,但我會假設它的樣子,說,Perl的。聽起來像是你想:

/^(?![-_])[-a-z\d_]{1,63}(?<![-_])$/i 

或者,如果Ruby沒有使用i標誌,只是[-a-zA-Z\d_]取代[-a-z\d_]

我使用[-a-zA-Z\d_],而不是更短[-\w]的原因是,雖然幾乎相當,\w將允許特殊字符,例如ä而不僅僅是ASCII類型字符。該行爲可以選擇性地在大多數語言中關閉,或者如果您願意,也可以允許。

character classes,一些更多的信息,並lookarounds

0

^[A-ZA-Z]([ - A-ZA-Z \ d] * [A-ZA-Z \ d])$

這只是在沒有回溯的情況下以有效的方式執行標準。它沒有檢查長度,但是Regex在這樣的事情上效率低下。只需檢查字符串長度(1到64個字符)。