2015-09-09 98 views
5

我試圖寫一個正則表達式使用C#/。淨匹配1-4字母數字後跟空格,然後是10位數字。捕捉是空格的數量加上字母數字的數量必須等於4,並且空格必須遵循字母數字,而不是散佈。正則表達式匹配一組字母后跟一組空格,使固定的字符總數

我完全喪失瞭如何做到這一點。我可以做^[A-Za-z\d\s]{1,4}[\d]{10}$,但是可以讓空間落在前四個字符的任何位置。或者我可以做^[A-Za-z\d]{1,4}[\s]{0,3}[\d]{10}$來保持空格在一起,但是這會在10位數字之前超過總共四個字符。

有效期: A12B1234567890 AB1 1234567890 AB 1234567890

無效: AB1 1234567890 (more than 4 characters before the numbers) A1B1234567890 (less than 4 characters before the numbers) A1 B1234567890 (space amidst the first 4 characters instead of at the end)

+3

請明確定義您的標準。我不確定在10位數字*之前,會有多於四個字符的數字。如果你至少需要1個空間會怎麼樣? '^ [A-ZA-Z \ d] {1,4} \ S {1,3} \ d {10} $'。 –

+3

包含一組匹配和不匹配將非常有幫助 – ryanyuyu

+0

要清楚,如果在開頭處有4個字母數字字符,那麼沒有空格是有效的,不是嗎? –

回答

6

你可以強制與向後看(?<=^[\p{L}\d\s]{4}),確保檢查有10位數前4點允許的字符:

^[\p{L}\d]{1,4}\s{0,3}(?<=^[\p{L}\d\s]{4})\d{10}$ 
         ^^^^^^^^^^^^^^^^^^^^ 

demo

如果你不這樣做計劃支持所有Unicode字母,只需將\p{L}替換爲[a-z]並使用RegexOptions.IgnoreCase即可。

+0

稍微更緊湊的替代:'^ [\ p {L} \ d]((<\ s)實施\ p {L} \ d] | \ S!){3} \ d {10} \ r? $'具有更少的可讀性:) – elgonzo

+1

@elgonzo:如果我有一個正則表達式產生相同的結果與替換,沒有它,我會選擇沒有。當對'A12B1234567890'測試,我正則表達式顯示在[regexhero.net]與您建議一個快15%的性能(http://regexhero.net/tester)。 –

+0

這很有趣。我只注意到我沒有使用非捕獲組交替 - 我不知道的性能損失的一小部分是因爲捕獲組什麼,如果有的話......我想我會測試:)我喜歡你的解決方案更多,因爲從左到右「閱讀」要容易得多,而我的真的不容易理解:) – elgonzo

4

這裏有您需要的正則表達式:

^(?=[A-Za-z0-9 ]{4}\d{10}$)[A-Za-z0-9]{1,4} *\d{10}$ 

它採用了lookahead(?= )如果它後面4個字符,測試,無論是alnum或空間,然​​後它返回到它的位置(字符串的開始,不消耗任何字符)。

一旦滿足這個條件,剩下的就是一個與你所嘗試的表達非常相似的表達式([A-Za-z0-9]{1,4} *\d{10})。

Online tester

+0

那麼,它也將匹配,如果有10個空格或所以本... :( – elgonzo

+0

@elgonzo:(?= [A-ZA-Z0-9] {4} \ d)沒有先行''可確保(alnum +空格)= 4 – Mariano

+0

媽的,我錯過了在先行模式的'\ D' - 我的壞你的正則表達式似乎是正確的......對不起:) – elgonzo

2

我知道這是愚蠢的,但要求必須完全正常工作。

^[A-Za-z\d]([A-Za-z\d]{3}|[A-Za-z\d]{2}\s|[A-Za-z\d]\s{2}|\s{3})[\d]{10}$ 
+1

這種方式可行,但stribizhev的後臺看起來更加優雅。謝謝你的幫助。 – jvance

2

不知道你在找什麼,但也許是:

^(?=.{14}$)[A-Za-z0-9]{1,4} *\d{10} 

demo

+0

這種方法清楚地表明瞭開箱即用的思想!與其試圖滿足所有條件,不如去尋找它背後的邏輯。 +1 – Mariano

+0

這也是我的建議。或者,長度檢查可以在正則表達式之外完成。 – nhahtdh

相關問題