2013-08-21 47 views
3

我正在尋找一些有關RegEx模式的指導。C#RegEx在管道分隔文件中查找空單元格

我有一個管道分隔的文件,我和我想刪除第四個單元格爲空的所有行。每行可以有任意數量的單元格。

我迄今爲止代碼:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Text.RegularExpressions; 
using System.Threading.Tasks; 

namespace EpicRemoveBlankPriceRecords 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string line; 

      // Read the file and display it line by line. 
      System.IO.StreamReader inFile = new System.IO.StreamReader("c:\\test\\test.txt"); 
      System.IO.StreamWriter outFile = new System.IO.StreamWriter("c:\\test\\test_out.txt"); 
      while ((line = inFile.ReadLine()) != null) 
      { 
       Match myMatch = Regex.Match(line, @".*\|.*\|.*\|\|.*"); 
       if (!myMatch.Success) 
       { 
        outFile.WriteLine(line); 
       } 
      } 

      inFile.Close(); 
      outFile.Close(); 

      //// Suspend the screen. 
      //Console.ReadLine(); 


     } 
    } 
} 

這是行不通的。我認爲這是因爲RegEx是「貪婪」 - 如果有空白單元格,就會匹配,因爲我沒有明確地說「除了管道字符之外的所有內容」。快速谷歌,我看到我可以在模式中使用[^ \ |]。

所以,如果我改變模式:

".*[^\|]\|.*[^\|]\|.*[^\|]\|\|.*" 

爲什麼不這項工作要麼?

猜猜我有點困惑,任何指針將不勝感激。

謝謝!

+0

你對我來說太快了 - 我注意到了這一點,並做了相應的編輯。不幸的是我的模式仍然沒有工作。 謝謝 – Ekins86

+2

是否有某些原因需要在這裏使用正則表達式?在我看來,像'string.IsNullOrEmpty(line.Split('|')[2])'這樣的事情會更容易。 –

+0

從1或從0開始的第3個項目? =) – Maslow

回答

1

這似乎對regexpal工作:

^[^|]*\|[^|]*\|[^|]*\|\|.* 
  • 單獨^意味着線
  • [^|]任何字符的開始除|
  • [^|]*匹配的零個或多個非|字符
  • +可對你的使用而言是錯誤的,但它意味着至少有一個,但找到的數量更多
  • .*意味着任何事情,儘可能多地發現它們。

測試數據:

  • ABC | 123 | 234 || 673
  • ABC | DEF || 123 | 456
  • ABC | 123 | 234 | 673 || AB
+0

nm,錯過了問題編輯 – Maslow

+0

建議的解決方案,帶有示例數據並突出顯示 - http://j.mp/14CryLM – Maslow

+0

抱歉編輯。但是,我們再次在文件中捕獲空白字段 - 例如。我抓住了abc | 123 | 234 | 673 | ab | – Ekins86

1

.*[^\|]表示零個或多個通配符(.*)和一個不是|[^\|])的字符。

此外,您需要在[]內轉義|

Regex.Match實際上並不匹配,所以它搜索,所以你需要^在正則表達式的開始(它表示字符串的開始)。因此也不需要追蹤.*

你不是想零個或多個字符不|,像這樣:

"^[^|]*\|[^|]*\|[^|]*\|\|" 

Test

爲什麼".*\|.*\|.*\|\|.*"沒有工作:

從上述原因

除了...

*貪婪並沒有改變多少(你可以把它非貪婪/做懶.*?)。問題是.也匹配|並且它回溯,所以.*將包含儘可能多或者很少的|以符合字符串的要求(是的,它會嘗試包含更多,因爲它是貪婪的,但這不會改變它是否找到某種東西,只有它找到的東西)。

你可以使用懶惰匹配和possessive quantifiers一起破解一些東西,但它最終會變得更復雜一些,更重要的是,我猜想,C#不支持這些。

+0

這似乎仍然捕獲,如果有空白(例如,如果第5個單元格是空白,它會捕獲單元格2,3,4和5) – Ekins86

+0

@ Ekins86這應該可以工作,只需將'^'和'$'添加到文件的開頭和結尾正則表達式。 –

+0

@ Ekins86似乎'匹配'不匹配,它搜索。有點編輯我的答案。 – Dukeling

2

你真的需要這裏的正則表達式嗎?

var lines = File.ReadLines(filename) 
      .Where(line => !String.IsNullOrWhiteSpace(line.Split('|')[3])); 

File.WriteAllLines(outfile, lines); 
+0

+1比正則表達式好得多 – Maslow