C#RegEx在管道分隔文件中查找空单元格

时间:2013-08-21 13:59:16

标签: c# regex regex-greedy

我正在寻找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是“贪婪的” - 如果有任何空白单元格,这匹配,因为我没有明确说“除了管道字符之外的所有东西”。一个快速的谷歌,我看到我可以使用模式中的[^ \ |]来做到这一点。

所以,如果我将模式更改为:

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

为什么这不起作用?

猜猜我有点困惑,任何指针都会非常感激。

谢谢!

3 个答案:

答案 0 :(得分:2)

你真的需要正则表达式吗?

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

File.WriteAllLines(outfile, lines);

答案 1 :(得分:1)

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

此外,您需要在|内转义[]

并且Regex.Match实际上并不匹配,它会搜索,因此您需要在正则表达式的开头^(表示字符串的开头)。

因此也不需要尾随.*

您需要零个或多个不是|的字符,如下所示:

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

Test

为什么".*\|.*\|.*\|\|.*"无效?

除上述原因外......

*贪婪并没有太大改变(你可以通过.*?来使它变得非贪婪/懒惰)。问题是.也匹配|并且它回溯,因此.*将包含与字符串匹配所需的|个{{1}}(是的) ,它会尝试包含更多,因为它是贪婪的,但这不会改变它是否找到了什么,只有它找到的东西。

你可以使用延迟匹配和possessive quantifiers一起破解某些东西,但最终会变得更复杂,更重要的是,我认为,C#不支持这些。

答案 2 :(得分:1)

这似乎适用于regexpal

^[^|]*\|[^|]*\|[^|]*\|\|.*
  • ^单独表示行首
  • [^|]|
  • 以外的任何字符
  • [^|]*匹配零个或多个非|字符
  • +可能对您的使用有误,但这意味着至少有一个,但发现的更多
  • .*意味着任何事情,以及尽可能多的事情。

测试数据:

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