2013-08-21 44 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