C# 使用LINQ以我想要的方式将字符串从制表符分隔的文本文件中获取到数组中
我有一个以制表符分隔的文本文件,其中包含以下格式的行: I000001\t I000002\t“诸如此类,诸如此类” 我试图在每个选项卡上拆分每一行,因此上面的行将被拆分为三个部分 在没有空格或引号的情况下,我能够根据需要拆分每一行,但在有空格或引号的情况下,我遇到了困难 下面是我用类似于上面的一行所做的尝试:C# 使用LINQ以我想要的方式将字符串从制表符分隔的文本文件中获取到数组中,c#,string,linq,tab-delimited,C#,String,Linq,Tab Delimited,我有一个以制表符分隔的文本文件,其中包含以下格式的行: I000001\t I000002\t“诸如此类,诸如此类” 我试图在每个选项卡上拆分每一行,因此上面的行将被拆分为三个部分 在没有空格或引号的情况下,我能够根据需要拆分每一行,但在有空格或引号的情况下,我遇到了困难 下面是我用类似于上面的一行所做的尝试: var x = from lines in data .Where(l => !string.IsNullOrEmpty(l)) .Select(l
var x = from lines in data
.Where(l => !string.IsNullOrEmpty(l))
.Select(l => l.Split('\t'))
select new
{
A = lines[0].Trim(),
B = lines[1].Trim(),
C = lines[2].Trim()
};
上面生成了一个索引为[0]、[1]、[2]的数组。每个索引都有三个由上述字符串组成的成员(参见下图)。它应该只有一个包含三个成员的索引
请注意数组中的第一项如何包含三个元素。数组中还有两个项目,在第一个项目下面。它们都有3个元素,这三个元素包含字符串的其余部分,并用双引号括起来
解决方案:
根据选定的答案,在引用语中的句子中有额外的制表符,从而将额外的项目添加到数组中。为了解决这个问题,我使用了一个正则表达式,改编自:
使用分隔符并将其设置为\t
这实际上是一个非常常见的问题,但人们通常会问逗号,而不是制表符 使用分隔符并将其设置为\t
这实际上是一个非常常见的问题,但人们通常会问逗号,而不是制表符 我建议使用以下代码:
var data = new[] {"I000001 \t I000002 \t \"Blah blah blah. Blah. Blah Blah\""};
var x = from lines in data
select (from s in lines.Split('\t')
where !string.IsNullOrEmpty(s)
select s.Trim())
.ToArray();
在本例中,只有一个制表符分隔的字符串,但如果输入数组中有更多的制表符分隔的字符串,则x将是字符串数组的枚举,由制表符分隔的子项组成。我建议使用以下代码:
var data = new[] {"I000001 \t I000002 \t \"Blah blah blah. Blah. Blah Blah\""};
var x = from lines in data
select (from s in lines.Split('\t')
where !string.IsNullOrEmpty(s)
select s.Trim())
.ToArray();
在本例中,只有一个制表符分隔的字符串,但如果输入数组中有更多的制表符分隔的字符串,则x将是字符串数组的枚举,由制表符分隔的子项组成。如果使用
拆分('\t')
,则会在每个制表符上拆分。。。因此,如果您的文本行按您所说的方式拆分,则它们中必须有制表符标记(在“”标记之间的文本中)。请检查这个。。。如果这样做,则可以在运行Linq查询之前使用正则表达式仅删除引号内出现的制表符。如果使用Split('\t')
,这将在每个制表符上拆分。。。因此,如果您的文本行按您所说的方式拆分,则它们中必须有制表符标记(在“”标记之间的文本中)。请检查这个。。。如果这样做,在运行Linq查询之前,您可以使用正则表达式仅删除引号内出现的制表符。不太确定您的问题是什么。。。你能解释得更清楚一点吗?我想你会感到困惑,因为调试器窗口显示了“I000001”
,但它只是意味着它是一个字符串。实际上它是I000001
。真的吗??我想我解释得很好。双引号内的字符串被拆分为多个部分,在数组中创建的对象超过了应有的数量。双引号中的字符串(或第三个制表符)应全部位于索引[2]处。@TimSchmelter以前抓住了我,但我确实意识到“I000001”
是i00001
。问题是引号中的字符串在三个不同的数组上被splt,每个数组都有三个项。如果我能让调试器窗口保持打开状态,我会截屏,你会明白的。你不能用LINQ可靠地做到这一点。使用答案中提到的TextFieldParser
。不太确定您的问题是什么。。。你能解释得更清楚一点吗?我想你会感到困惑,因为调试器窗口显示了“I000001”
,但它只是意味着它是一个字符串。实际上它是I000001
。真的吗??我想我解释得很好。双引号内的字符串被拆分为多个部分,在数组中创建的对象超过了应有的数量。双引号中的字符串(或第三个制表符)应全部位于索引[2]处。@TimSchmelter以前抓住了我,但我确实意识到“I000001”
是i00001
。问题是引号中的字符串在三个不同的数组上被splt,每个数组都有三个项。如果我能让调试器窗口保持打开状态,我会截屏,你会明白的。你不能用LINQ可靠地做到这一点。使用回答中提到的TextFieldParser
。尝试了TextFieldParser
,但得到了相同的结果。@MattSull87-您设置了HasFieldsEnclosedInQuotes属性吗?尝试了TextFieldParser
但得到了相同的结果。@MattSull87-您设置了HasFieldsEnclosedInQuotes属性吗?您是对的。文本行最初可能是在段落中,导致附加选项卡?手动删除它们可以使其按需要工作,但我将使用正则表达式删除引用中的任何内容。为完整起见,请使用正则表达式编辑您的答案。@MattSull87,您的编辑因更改答案的含义或其他原因而被几位版主拒绝。。。也许你应该在问题的末尾加上正则表达式?假设这是有意义的。很快将更新问题。你是对的。文本行最初可能是在段落中,导致附加选项卡?手动删除它们可以使其按需要工作,但我将使用正则表达式删除引用中的任何内容。为完整起见,请使用正则表达式编辑您的答案。@MattSull87,您的编辑因更改答案的含义或其他原因而被几位版主拒绝。。。也许你应该在问题的末尾加上正则表达式?假设这是有意义的。稍后将更新问题。