2015-06-03 21 views
0

我正在編寫一個代碼,它將查看名爲a的文本文件中的組,並且如果該代碼中的某行包含「Savings Found」一詞,它將寫出該行,並且如果有節省30%或更多,它會在前面放置一個星號,如果它包含30%或更多,並且節省500美元或更多,它會放置兩個星號。下面我有一個採樣數據,控制檯需要什麼樣子的例子,代碼我迄今:修復System.FormatException

string find = "Savings found:"; 
    foreach (var line in a.Where(w => w.Contains(find))) 
     { 
      var subStr = line.Substring(line.IndexOf(find) + find.Length); 
      var startIndex = subStr.IndexOf('('); 
      var endIndex = subStr.IndexOf(')'); 

      var savings = double.Parse(subStr.Substring(0, startIndex - 1).Trim()); 
      var percent = double.Parse(subStr.Substring(startIndex + 1, endIndex - startIndex - 2).Trim()); 

      Console.WriteLine("{0}{1}{2}", (percent >= 30) ? "*" : string.Empty, 

      (percent >= 30 && savings >= 500) ? "*" : string.Empty, 
                 line); 
     } 

數據採樣/例如

* 5/21/2015 11:55:56 PM | Batch 6|386/767|50.33 %|CH2M-R|Processed NXRMN5...Checking refundable and non-refundable fares. Traditional Booking. Inside ticketing window. Minimum Savings Required: $131.00. Actual Savings: $257.18. Savings found: $257.18 (11.55 %). Savings were previously found. 

,我遇到的問題是我得到一個FormatException錯誤,我想我知道問題是什麼。問題是subString的值是257.18以及之後的所有內容。我不想要所有的東西,我只想要這個號碼。我可以做些什麼來擺脫額外的垃圾,以便它可以編譯?

這個問題類似於先前提出的一個問題,但是在那個答案中,我得到一個ArgumentIndexOutOfBounds異常,試圖解決它,但並沒有在實際解決問題方面走得太遠,因此推理這個問題。

+0

「這樣它可以編譯?」這似乎是一個運行時錯誤,而不是編譯器錯誤。 –

+0

@ThomasWeller這是一個運行時錯誤。我爲這個錯誤道歉。感謝您指出它我欣賞它 – user4970927

+0

我想你在解析方法中包含'$'和'%',它不起作用。 –

回答

0

您可以使用正則表達式爲:

foreach(string line in a) 
{ 
    Match m = Regex.Match(line, @"Savings\s+found:\s*\$(?<savings>\d+\.\d+)\s*\(\s*(?<percent>\d+\.\d+)\s*%"); 
    if (m.Success) 
    { 
     decimal savings = decimal.Parse(m.Groups["savings"].Value, CultureInfo.InvariantCulture); 
     decimal percent = decimal.Parse(m.Groups["percent"].Value, CultureInfo.InvariantCulture); 
     string prefix = string.Empty; 
     if (percent >= 30) 
     { 
      if (savings >= 500) 
       prefix = "**"; 
      else 
       prefix = "*"; 
     } 
     Console.WriteLine(prefix + line); 
    } 
} 
-1

我假設你想在「發現儲蓄:」 正則表達式應該幫助後的數字和小數值。 Theres可能比這更好,但這應該起作用。

string find = "Savings found:"; 
    foreach (var line in a.Where(w => w.Contains(find))) 
     { 
      //line = 5/21/2015 11:55:56 PM | Batch 6|386/767|50.33 %|CH2M-R|Processed NXRMN5...Checking refundable and non-refundable fares. Traditional Booking. Inside ticketing window. Minimum Savings Required: $131.00. Actual Savings: $257.18. Savings found: $257.18 (11.55 %). Savings were previously found." 
      Regex regex = new Regex(@"Savings found:\s\$[0-9]*.[0-9]{2}\s*\([0-9]*.[0-9]{2} %\)"); 
      Match match = regex.Match(line); 
      var savingsFoundSection = match.Value; 

      MatchCollection matches = Regex.Matches(savingsFoundSection, @"[0-9]*\.[0-9]{2}"); 
      String savingsString = matches[0].Value; 
      String percentString = matches[1].Value; 
      //savingString = "257.18" 
      //precentString = "11.55" 

      var savings = double.Parse(savingsString); 
      var percent = double.Parse(percentString); 

      Console.WriteLine("{0}{1}{2}", (percent >= 30) ? "*" : string.Empty, 

      (percent >= 30 && savings >= 500) ? "*" : string.Empty, 
                 line); 
     } 
+0

不幸的是,這是行不通的。當我運行調試器時,var儲存行會彈出一個ArgumentOutOfRangeException。說長度不能小於0 – user4970927

+0

哎呦,堅持一秒鐘 –

+0

修復它,測試它 –

0

看來你能重現錯誤。那很棒!可重現的問題通常很容易解決。

假設你有沒有其他工具,如OzCode或ReSharper的,這將是調試的方式和固定它:

一旦你知道其中發生了錯誤的行,使語句簡單。也就是說,將其分解成更小的部分。在你的情況下

var savings = double.Parse(subStr.Substring(0, startIndex - 1).Trim()); 

是否有太多的東西,所以你不知道問題是什麼。拆分成:

var savingsString = subStr.Substring(0, startIndex - 1).Trim(); 
var savings = double.Parse(savingsString); 

因爲那樣的話,在調試過程中,可以將手錶添加到savingsString,並認爲它是 Watch windows in VS

你可以考慮一下這樣的事實,爲什麼「$ 257.18」無法解析,找到反措施。之前的代碼,你甚至不知道導致問題的輸入。

潛在的對策:

  • 刪除美元:.Replace("$","")
  • 開始後的字符串:subStr.Substring(1, ...)
  • savingsString = savingsString.Trim('$');如果你不能確定它是否是在開始或結束

從你的程序代碼看來,你知道所有必需的方法,你只是不知道如何調試。

繼續使用這種方法,您將能夠修復代碼的所有問題以及未來的問題。

而且:我不能推薦Regex。它們是不可讀的,沒有人想維護它們。

+1

我懷疑Find/Substring/Replace的混合比正則表達式更可讀。 –

+0

我同意@UlugbekUmirov,並建議他進行單元測試?或一次只測試一個單位的代碼?因爲它們不是一回事。 –

+1

@JasonPortnoy:我同意。單元測試的概念對於OP來說可能太多了。刪除該部分。 –