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