2009-08-26 54 views
2

考慮一個字符串,它看起來像這樣:C#:判斷字符串是否像這種模式;可能正則表達式

RR1 S5 C92

這是一個農村的路線地址外的鎮郵件投遞:農村路線,站點,車廂。每個字母后跟一個數字和一個空格。通常一到三位數字,但你永遠不知道它可能有多少個數字!如果用戶懶惰,他們可能輸入了零個,一個或多個空格。

問題: 您將使用什麼正則表達式來確定給定的字符串是否與此模式匹配?

它的用法是這樣的:

string ruralPattern; //a regex pattern here 
bool isRural = Regex.Match(someString, ruralPattern); 

更新:謝謝您的建議!性能和使用將在一個靜態方法中從一個Web服務調用。根據此模式檢查的字符串將最多爲50個字符。該方法將大約每5秒調用一次。任何建議保持靜態?非常感激!

回答

9

這應該工作:

^[Rr][Rr]\d+ *[Ss]\d+ *[Cc]\d+$ 

或按其他評論

^[Rr][Rr][0-9]+ *[Ss][0-9]+ *[Cc][0-9]+$ 

這一切意味着什麼:

  • ^- 串
  • 開始
  • [RR] - 下一個字符必須是R或r
  • [RR] - 下一個字符必須是R或R
  • \ d +或[0-9] + - 下一部分必須是1個或多個數字
  • (空格)* - 允許0或多個空格
  • [SS] - 下一個字符必須是S或S
  • \ d +或[0-9] + - 下一部分必須是1個或多個數字
  • (空格)* - 允許0或多個空格
  • [Cc] - 下一個字符必須是C或c
  • \ d +或[0-9] + - 下一部分必須是1或多個數字
  • $ - 字符串結尾

可能有一個更優雅的解決方案,但是這很容易閱讀。

編輯:更新,包括一些評論

+0

簡單性對於正則表達式來說是件好事。 – 2009-08-26 22:26:58

+0

肯定......我希望更多的人會分解他們的解決方案,因爲我已經在上面讓他們更容易理解,因爲正則表達式不是最易讀的語法。 – Kelsey 2009-08-26 22:36:50

+0

@凱爾西:感謝您解釋正則表達式語法 – escist 2013-03-20 13:56:10

3

的輸入......怎麼

someString = someString.Trim(); // eliminate leading/trailing whitespace 
bool isRural = Regex.Match(
    someString, 
    @"^rr\d+\s*s\d+\s*c\d+$", 
    RegexOptions.IgnoreCase); 

這消除了在圖案內大/小寫切換,並使用\s允許任何(非換行符)空白字符(例如製表符)。如果您只需要空格,則應將'\s'更改爲' '

+1

+1,這是最簡單也是最正確的答案,但**,請注意'\ d'不僅僅匹配'[0-9]'。它匹配char.IsDigit返回true的任何字符,在我的計數中包含一些** 230 ** unicode代碼點。 – 2009-08-27 01:14:03

+0

是的,的確如此,並且可以對'\ s'('char.IsWhiteSpace')進行類似的聲明。 – bobbymcr 2009-08-27 03:23:20

+0

@P - 感謝您對「\ d」的洞察! – 2009-08-27 15:25:03

1

讓我們澄清如下推定:

  1. 有三個部分的字符串。
  2. 第1部分始終以RR大寫或小寫開頭,並以一個或多個小數位結尾。
  3. 第2節始終以S大寫或小寫開頭,並以一位或多位小數位結尾。
  4. 第3節總是以C開頭或以下,並以一位或多位小數位結尾。

爲簡單起見,以下內容就足夠了。

[Rr][Rr][0-9]+[ ]+[Ss][0-9]+[ ]+[Cc][0-9]+ 
  1. [RR]指恰好一個字母R, 大寫或小寫。
  2. [0-9]意味着精確的一位小數點 數字。
  3. [0-9] +表示至少一個或多個 的十進制數字。
  4. [] +表示至少有一個或多個 空格。

但是,通常,當您使用正則表達式時,我們還會檢測各個部分以利用匹配功能來幫助我們將各個部分值分配給它們各自的/單獨的變量。

因此,下面的正則表達式更有幫助。

([Rr][Rr][0-9]+)[ ]+([Ss][0-9]+)[ ]+([Cc][0-9]+) 

讓該正則表達式應用於字符串

string inputstr = "Holy Cow RR12 S53 C21"; 

這是你的正則表達式匹配將讓你知道:

start pos=9, end pos=21 
Group(0) = Rr12 S53 C21 
Group(1) = Rr12 
Group(2) = S53 
Group(3) = C21 

有三對橢圓/圓括弧的。 每對是正則表達式編譯器調用組的一部分字符串。

正則表達式編譯器將調用

  1. 比賽整個匹配的字符串爲0組
  2. 農村的路線爲1組
  3. 網站作爲第2組和
  4. 貨艙中組3

當然,組1,3將遇到匹配,當且僅當組0具有匹配。

因此,你的算法會利用與下面的僞代碼

string postalstr, rroute, site, compart; 
if (match.group(0)!=null) 
{ 
    int start = match.start(0); 
    int end = match.end(0); 
    postalstr = inputstr.substring(start, end); 

    start = match.start(1); 
    end = match.end(1); 
    rroute = inputstr.substring(start, end); 

    start = match.start(2); 
    end = match.end(2); 
    site = inputstr.substring(start, end); 

    start = match.start(3); 
    end = match.end(3); 
    compart = inputstr.substring(start, end); 
} 

此外,你可能要進入與列的數據庫表:RR,網站,艙室,但你只想要數字輸入沒有字母「rr」,「s」或「c」。 這將是使用嵌套分組的正則表達式。

([Rr][Rr]([0-9]+))[ ]+([Ss]([0-9]+))[ ]+([Cc]([0-9]+)) 

而且匹配會讓你知道什麼時候發生匹配組0以下:

start=9, end=21 
Group(0) = Rr12 S53 C21 
Group(1) = Rr12 
Group(2) = 12 
Group(3) = S53 
Group(4) = 53 
Group(5) = C21 
Group(6) = 21 
0

FYI:如果你要使用這個正則表達式來測試大量的數據,你最好的選擇就是告訴.NET預編譯它 - 它將被編譯成IL並提供性能提升,而不是每次都簡單地解釋RegEx模式。指定爲上哪個類包含你的方法靜態成員,像這樣:

private static Regex re = new Regex("pattern", RegexOptions.Compiled | RegexOptions.IgnoreCase); 

...和方法來測試一個字符串是否匹配模式是...

bool matchesString = re.IsMatch("string"); 

好運。

+1

*可能*。 'RegexOptions.Compiled'並不總是一個勝利,並且分析是必要的。參見:http://www.codinghorror.com/blog/archives/000228.html和http://stackoverflow.com/questions/414328/using-static-regex-ismatch-vs-creating-an-instance-of-正則表達式/ 414411#414411 – 2009-08-27 02:35:20

+0

謝謝Tullo和PDaddy。圍繞預期用法的問題更新! – 2009-08-27 03:38:35

相關問題