2011-10-18 40 views
0

我想開始知道如何去符合下列條件創建一個正則表達式:正則表達式驗證,並提取字符串以十進制或分數

  1. 字符串必須以小數或分數
  2. 啓動
  3. 十進制應該是正數,最多可以保留兩位小數
  4. 分數應該是它自己的一個分數或一個整數和分數,即1 1/2,3/4,並用空格分隔。 (可能是冷靜,如果有人寫1和1/2,這新的將是1 1/2,但不是必需
  5. 列表項

我想驗證一個字符串,或爲十進制開始或一部分和得到提取的值在它外面

有效實例

"1 cup" = VALID = Extracted values: (1) (cup) 
".5 cup" = VALID = Extracted values: (0.5) (cup) 
"1.0 cup" = VALID = Extracted values: (1.0) (cup) 
"1.10 cup" = VALID = Extracted values: (1.10) (cup) 
"1/2 cup" = VALID = Extracted values: (1/2) (cup) 
"1 1/2 cup" = VALID = Extracted values: (1 1/2) (cup) 
"1 and 1/2 cup" = VALID = Extracted values: (1 1/2) (cup) 
"1 and a 1/2 cup" = VALID = Extracted values: (1 1/2) (cup) 
"1 & 1/2 cup" = VALID = Extracted values: (1 1/2) (cup) 

無效實例

"1 1/2 1/4 1/4 cup" = INVALID (only allow whole and fraction, or one fraction) 
"1.034 cup" = INVALID (2 decimal places only)  
"cup 1/2" = INVALID (not the start of the string) 

編輯 我到目前爲止有:

解析分數:

\d*\s*(and*|and a*|\s*)\d+\/?\d*(.*)$ 

解析小數:

^\d{0,2}(\.\d{1,2})?$ 

我的合併版本:

(\d*\s*&|and*|and a*|\s*\s*\d+\/?\d*)|(\d{0,2}\.\d{1,2})*(.*)$ 

只是不知道如何正確地加入2,它可以更好地優化?和無效的一個仍然解析

任何幫助,將不勝感激,謝謝

問候DotnetShadow

+0

我已編輯我的帖子,包括我目前爲止如果有幫助 – DotnetShadow

回答

3

我下面的作品與你的上述實例(使用Regex Hero測試):

^(?<WholeNumber>\d+){0,1}(?:\s(?<JoinWord>&|and|and\sa)?\s?)?(?<Decimal>\.\d{1,2})?(?<Fraction>(?<Numerator>\d+)\/(?<Denominator>\d+)){0,1}(?:\s(?<Unit>cup))$ 

您會注意到我爲各種組件使用了命名捕獲組。我會留給你解析出這些組並加以有意義的加入(例如,將整數加到十進制值除以100後加上分子除以分母)。

您還可以爲其他受支持的「單元」以及其他支持的「連接詞」添加其他模式。

編輯:根據我的意見添加了我的建議。

+0

而實際上,您可能會使用(? \ d +)代替整個數字部分... – Reddog

+0

也許移動第一個「\ s」 (空格)以某種方式加入「JoinWord」捕獲組。 – Reddog

+0

非常感謝你,非常感謝你。我可以從這裏學到很多 – DotnetShadow

1

我不認爲你需要正則表達式來解決這個問題。考慮以下解決方案:

  1. 編寫函數IsFraction(字符串s),檢查字符串是否是有效的分數(例如,它可以是3/2?)。
  2. 拆分輸入字符串,檢查最後一項不是任何數字 - 這將是單位。
  3. 刪除列表中的所有非數字和非分數項目。
  4. 驗證剩餘的物品數量是否小於3.
  5. 如果物品的數量是2,首先驗證是自然數,第二是小數。 - >結果
  6. 如果count爲1,請驗證它是分數還是小數。 - >結果

更多的時間(可能)爲初步寫作,但更容易維護和擴展。

P.S.使用int.TryParsedecimal.TryParse以及在IsFraction之內。

+0

感謝您的好選擇會嘗試 – DotnetShadow