2013-03-07 130 views
4

我正在嘗試使用正則表達式查找格式正確的貨幣或字符串的範圍。我碰巧使用C#,所以正則表達式就是這樣格式化的。貨幣範圍正則表達式

例如,我希望能夠找到:

$10,000,000 to $20M 
$10k-$20k 
100.23k - 200.34k 
$20000 and $500600 
3456646 to 4230405 

它不應該匹配:

$10,0000,000 to $20,000,000 //extra zero in first number 
20k xyz 40k //middle string does not match a range word 

這裏是我的正則表達式到目前爲止:

(^|\s|\$)([1-9](?:\d*|(?:\d{0,2})(?:,\d{3})*)(?:\.\d*[1-9])?|0?\.\d*[1-9]|0)(|m|k)(?:|\s)(?:|to|and|-|,)(?:|\s)(|\$)([1-9](?:\d*|(?:\d{0,2})(?:,\d{3})*)(?:\.\d*[1-9])?|0?\.\d*[1-9]|0)(\s|m|k) 

它似乎工作得很好,但有時會匹配我不指望它的項目。示例:

1985 xyz 1999 //2 matches, both numbers without xyz 
$10,000,000 xyz $20000000 //1 match on the $2000000 
$10,000,0000 to $20,000,000 //1 match on the $10,000,0000 (extra zero on end) 

我錯過了什麼?用正則表達式來做這件事是愚蠢的嗎?

+6

我的看法是,所有不適合80字符行的正則表達式太大,無法讀取或調試。一旦你的正則表達式增長得比建議的邊界大,我會建議編寫一個簡單的解析器。 – 2013-03-07 17:34:33

+0

@Pieter是的,我有一種感覺自己變得太久了。一旦你感覺如此接近,很難從它退縮。也許我會嘗試提前刪除逗號,這會簡化它。 – robr 2013-03-07 17:49:13

+0

但是可能會更快:編寫(並研究和測試)正則表達式,或者只寫一個簡單的解析器? – 2013-03-07 17:52:25

回答

2

在這裏你去哥們

(?<=^|\s)\$?\d+((\.\d{2})?(k|M)|(,\d{3})*)\b\s*(to|-|and)\s*\$?\d*((\.\d{2})?(k|M)|(,\d{3})*)(\s|$) 

看到它在action

這部分

\d+((\.\d{2})?(k|M)|(,\d{3})*) 

在重演。所以最好把它保存在一個常量中,並將這個正則表達式連接在一起。

String moneyPattern = @"\d+((\.\d{2})?(k|M)|(,\d{3})*)"; 
String rangeConnectorPattern = @"\b\s*(to|-|and\b)\s*"; 
String moneyRangePattern = @"(?<=^|\s)"+ 
    moneyPattern + rangeConnectorPattern + moneyPattern + 
    "(\s|$)"; 

無需編寫解析器。