Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#RegEx在管道分隔文件中查找空单元格_C#_Regex_Regex Greedy - Fatal编程技术网

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

C#RegEx在管道分隔文件中查找空单元格,c#,regex,regex-greedy,C#,Regex,Regex Greedy,我正在寻找一些关于正则表达式模式的指导 我有一个以管道分隔的文件,我和我想删除第四个单元格为空的所有行。每行可以有任意数量的单元格 到目前为止,我的代码是: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace EpicRe

我正在寻找一些关于正则表达式模式的指导

我有一个以管道分隔的文件,我和我想删除第四个单元格为空的所有行。每行可以有任意数量的单元格

到目前为止,我的代码是:

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();


        }
    }
}
这不管用。我认为这是因为正则表达式是“贪婪的”——这与是否有空白单元格相匹配,因为我没有明确地说“捕获除管道字符以外的所有内容”。快速搜索一下,我发现我可以在模式中使用[^\|]来实现这一点

因此,如果我将模式更改为:

 ".*[^\|]\|.*[^\|]\|.*[^\|]\|\|.*"
为什么这也不行

我想我有点困惑,任何指点都将不胜感激


谢谢

*[^\\
表示零个或多个通配符(
*
)和一个非
[^\\\]
)字符

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

并且实际上不匹配,它进行搜索,因此您需要在正则表达式的开头(指示字符串的开头)添加
^

因此,也不需要尾部的
*

相反,您需要零个或多个非
|
字符,如下所示:

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

为什么
“*\\\\\\\\\\\\\\\\\\\\\\\\..*”
不起作用:

除了上述原因

*
贪婪其实改变不了多少(你可以通过
*?
让它变得不贪婪/懒惰)。问题是
也会匹配
|
并且会回溯,因此
*
会根据需要包含尽可能多或尽可能少的
|
,以匹配字符串(是的,它会尝试包含更多内容,因为它很贪婪,但这不会改变它是否找到某个内容,只会改变它找到的内容)

您可以使用惰性匹配和,将一些东西组合在一起,但它最终会变得更加复杂,而且更重要的是,我认为C#不支持这些功能。

这似乎适用于:

  • ^
    单独表示行的开始
  • [^ |]
    |
  • [^ |]*
    匹配零个或多个非
    字符
  • +
    对于您的使用可能是错误的,但它意味着至少有一个,而且无论找到多少
  • *
    意味着任何东西,并尽可能多地找到它们
测试数据:

  • abc | 123 | 234 | 673
  • abc | def | 123 | 456
  • abc | 123 | 234 | 673 | ab

这里真的需要正则表达式吗

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

File.WriteAllLines(outfile, lines);

你对我来说太快了——我注意到了这一点,并进行了相应的编辑。不幸的是,我的模式仍然不起作用。谢谢你为什么需要在这里使用正则表达式?在我看来,执行类似于
string.IsNullOrEmpty(line.Split(“|”)[2])的操作会容易得多。从1或从0开始的第3项?=)谢谢@Maslow-我编辑成第四名clarification@MagnusGrindalBakken我真的很想了解更多关于regex的信息,但你是对的-拆分是这里最简单的解决方案。如果文件后面有空白单元格,这似乎仍然适用(例如,如果第5个单元格是空白的,它适用于单元格2、3、4和5)@Ekins86这应该行得通,只需将
^
$
添加到正则表达式的开头和结尾。@Ekins86似乎
匹配
不匹配,它会搜索。我的答案被编辑了一点。很抱歉被编辑了。尽管如此,我们还是在文件的后面捕捉到了空白字段——例如,我捕捉到abc | 123 | 234 | 673 | ab | |谢谢@Maslow。我已经接受了这个答案,因为它满足了我的需要,并且有很好的澄清-看起来我的错误是我不需要从[]中逃离管道更新了带有更多测试数据的链接,并且
+
不正确。
var lines = File.ReadLines(filename)
           .Where(line => !String.IsNullOrWhiteSpace(line.Split('|')[3]));

File.WriteAllLines(outfile, lines);