2011-03-04 151 views
1

我需要匹配這個字符串011Q-0SH3-936729但不345376346asfsdfgsfsdf 它包含字符,數字和連使用正則表達式匹配包含數字字母和破折號

模式可能是011Q-0SH3-936729011Q-0SH3-936729-SDF3或​​或字符串011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729,我希望它能匹配其中任何一個。原因是我真的不知道該格式是否已修復,我也找不到任何方法,因此我需要爲具有任何數量的破折號的模式想出一個通用解決方案,並且該模式會重複出現任意數量的倍。

對不起,這可能是一個愚蠢的問題,但我真的很喜歡正則表達式。

TIA

+0

請問模式總是在字符串中的第五和第十指數幾許? – Oded 2011-03-04 09:18:13

+0

我們知道有多少破折號?破折號之間是否總有規則大小的字母/數字組?字母在A-Z中? ...還是字符集的更大部分? – spender 2011-03-04 09:18:37

+0

是在一個固定的位置破折號,或者他們可以在任何地方? (ROFL ...我太慢了:) – 2011-03-04 09:18:53

回答

4
foundMatch = Regex.IsMatch(subjectString, 
    @"^    # Start of the string 
    (?=.*\p{L})  # Assert that there is at least one letter 
    (?=.*\p{N})  # and at least one digit 
    (?=.*-)   # and at least one dash. 
    [\p{L}\p{N}-]* # Match a string of letters, digits and dashes 
    $    # until the end of the string.", 
    RegexOptions.IgnorePatternWhitespace); 

應該做你想做的。如果用字母/數字你的意思是「只有ASCII字母/數字」(而不是國際/ Unicode字母,也是如此),然後用

foundMatch = Regex.IsMatch(subjectString, 
    @"^    # Start of the string 
    (?=.*[A-Z])  # Assert that there is at least one letter 
    (?=.*[0-9])  # and at least one digit 
    (?=.*-)   # and at least one dash. 
    [A-Z0-9-]*  # Match a string of letters, digits and dashes 
    $    # until the end of the string.", 
    RegexOptions.IgnorePatternWhitespace | RegexOptions.IgnoreCase); 
+0

這會匹配字符串'-0-A-'(首尾的破折號) – Alex 2011-03-04 10:39:31

+0

難道OP禁止呢? – 2011-03-04 12:54:56

+0

不,我沒有,但我確實提到,如果是這樣的話,那麼迎合他們並不是一件沉悶的事情。如果該字符串中有短劃線,只要它們構成相同字符串的一部分即可。這適用於我所需要的。謝謝蒂姆,你是一個天才。感謝您解釋您的正則表達式以及它的工作原理,您應該得到+1,我今天學到了一些東西。 – n4rzul 2011-03-10 08:01:28

4

編輯:

這將匹配任何在您的意見中提供的關鍵的:

^[0-9A-Z]+(-[0-9A-Z]+)+$ 

,這意味着用數字或字母鍵啓動,必須​​在leats一個短劃線符號:

+0

請參閱上面的 – n4rzul 2011-03-04 09:29:01

+0

@ n4rzul的問題我的兩個額外的評論:看到我的更新答案 – Alex 2011-03-04 09:37:17

+1

這符合'A-A'或'0-0'問題(見第二句)。 – 2011-03-04 10:11:02

0

最幼稚的實現永遠(可能讓你開始):

([0-9]|[A-Z])+(-)([0-9]|[A-Z])+(-)([0-9]|[A-Z])+ 

使用Regex Coach進行了測試。

編輯:

這隻匹配三組;另外這裏,稍微好一點:

([0-9A-Z]+\-)+([0-9A-Z]+) 
+0

嘿嘿,真的很天真:)看到我對上述問題的兩個額外的意見。 – n4rzul 2011-03-04 09:28:23

0

沒有關於破折號或其他的規律性更多的信息,這是最好的,我們可以這樣做:

Regex.IsMatch(input,@"[A-Z0-9\-]+\-[A-Z0-9]") 

雖然這也將匹配-A-0

0

你將正則表達式的整個字符串(即驗證或過濾) ?如果是這樣,蒂姆的答案應該把你的權利。但是如果你從一個更大的字符串中抽取比賽,它會變得更加複雜。下面是我會怎麼做:

string input = @"Pattern could be 011Q-0SH3-936729 or 011Q-0SH3-936729-SDF3 or 000-222-AAAA or 011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729 but not 345-3763-46 or ASFS-DFGS-FSDF or ASD123FGH987."; 

Regex pluckingRegex = new Regex(
    @"(?<!\S)   # start of 'word' 
     (?=\S*\p{L}) # contains a letter 
     (?=\S*\p{N}) # contains a digit 
     (?=\S*-)  # contains a hyphen 
     [\p{L}\p{N}-]+ # gobble up letters, digits and hyphens only 
     (?!\S)   # end of 'word' 
    ", RegexOptions.IgnorePatternWhitespace); 

foreach (Match m in pluckingRegex.Matches(input)) 
{ 
    Console.WriteLine(m.Value); 
} 

輸出:

011Q-0SH3-936729 
011Q-0SH3-936729-SDF3 
000-222-AAAA 
011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729-011Q-0SH3-936729

負lookarounds作爲「字」的界限:他們確保匹配的子開始無論是在字符串的開頭或空格後字符((?<!\S))和結束或者在字符串的末尾或空白字符((?!\S))之前。

三個積極向前看符號的工作就像添的,除了他們使用\S*跳過任何的第一個字母/數字/連字符之前。在這種情況下,我們不能使用.*,因爲這可以讓它跳到下一個單詞或下一個單詞等等,從而擊敗了lookahead的目的。

相關問題