C# 使用流读取器将多行合并为一个字符串
我有一个大小适中的文件95K行,需要解析。对于以下示例数据C# 使用流读取器将多行合并为一个字符串,c#,parsing,C#,Parsing,我有一个大小适中的文件95K行,需要解析。对于以下示例数据 <FIPS>10440<STATE>AL<WFO>BMX 8 32.319 32.316 -86.484 -86.487 32.316 -86.484 32.316 -86.484 102 32.501 31.965 -85.919 -86.497 32.496 -86.248 32.448 -86.181
<FIPS>10440<STATE>AL<WFO>BMX
8 32.319 32.316 -86.484 -86.487 32.316 -86.484
32.316 -86.484
102 32.501 31.965 -85.919 -86.497 32.496 -86.248
32.448 -86.181 32.432 -86.189 32.433 -86.125 32.417 -86.116
32.406 -86.049 32.419 -86.023 32.337 -85.991 32.333 -85.969
32.276 -85.919 32.271 -85.986 32.250 -85.999 31.968 -85.995
31.965 -86.302 32.052 -86.307 32.051 -86.406 32.245 -86.410
32.276 -86.484 32.302 -86.491 32.332 -86.475 32.344 -86.497
32.364 -86.492 32.378 -86.463 32.405 -86.460 32.414 -86.396
32.427 -86.398 32.433 -86.350 32.412 -86.310 32.441 -86.325
32.487 -86.314 32.473 -86.288 32.488 -86.260 32.501 -86.263
32.496 -86.248
我需要做的是从一个FIP读到下一个FIP,并将每组中的行组合成一条巨大的行,如下所示
<FIPS>10440<STATE>AL<WFO>BMX 8 32.319 32.316 -86.484 -86.487 32.316 -86.484 32.316 -86.484...
<FIPS>10440<STATE>AL<WFO>BMX 102 32.501 31.965 -85.919 -86.497 32.496 -86.248 32.448 -86.181...
我目前有以下关于我今天的第六个变体的代码。我错过了什么
using (var reader = new StreamReader(winterBoundsPath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Trim();
if (!Char.IsLetter(line[0]))
{
if (line.Contains("<FIPS>"))
{
var lineReplace = line.Replace('<', ' ').Replace('>', ' ');
string[] rawData = lineReplace.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
temp = new WinterJsonModel
{
FIPS = rawData[1],
State = rawData[3],
Center = rawData[5],
polyCoords = new List<polyCoordsJsonData>()
};
}
else
{
string[] rawData2 = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
if (rawData2.Count() > 1)
{
allValues.Add(listPointValue);
listPointValue = new List<string>();
}
// Add values to line
foreach (string value in rawData2)
{
listPointValue.Add(value);
}
}
}
}
reader.Close();
}
根据您提供的示例判断,换行符是CRLF字符。这意味着你只需要知道两件事。 1.如果该行包含FIPS作为字符串文字并作为标记括起 2.如果您到达了有回车符的行的末尾 我现在将忽略JSON位,因为它不是您问题的一部分。我假设这意味着您已经很好地处理了JSON,如果我们按照您想要的方式得到这些字符串,您就可以从那里得到它
var x = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Trim();
if (line.Contains("<FIPS>"))
{
x.Add(line.Replace(Environment.NewLine, " "));
}
else
{
var s = String.Concat(x.Last(), line.Replace(Environment.NewLine, string.Empty), " ");
x[x.Count - 1] = s;
}
}
这里的要点主要是将数据的组织与实际放入对象的数据分开。从这里,您可以在foreach中遍历列表,根据string.Split的结果创建新对象。对列表中的每个字符串进行拆分。我解析文本文件已有40多年了。下面的代码是我所做工作的示例
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Oppgave3Lesson1
{
class Program
{
const string FILENAME = @"c:\temp\test.txt";
static void Main(string[] args)
{
WinterJsonModel data = new WinterJsonModel();
data.ParseFile(FILENAME);
}
}
public class WinterJsonModel
{
public static List<WinterJsonModel> samplData = new List<WinterJsonModel>();
public string fips { get; set; }
public string state { get; set; }
public string wfo { get; set; }
public List<Group> groups = new List<Group>();
public void ParseFile(string winterBoundsPath)
{
WinterJsonModel winterJsonModel = null;
Group group = null;
List<KeyValuePair<decimal, decimal>> values = null;
using (var reader = new StreamReader(winterBoundsPath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Trim();
if (line.Length > 0)
{
if (line.StartsWith("<FIPS>"))
{
winterJsonModel = new WinterJsonModel();
WinterJsonModel.samplData.Add(winterJsonModel);
string[] rawData = line.Split(new char[] { '<', '>' }, StringSplitOptions.RemoveEmptyEntries);
winterJsonModel.fips = rawData[1];
winterJsonModel.state = rawData[3];
winterJsonModel.wfo = rawData[5];
group = null; // very inportant line
}
else
{
decimal[] rawData = line.Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries).Select(x => decimal.Parse(x)).ToArray();
//if odd number of numbers in a line
if (rawData.Count() % 2 == 1)
{
group = new Group();
winterJsonModel.groups.Add(group);
group.id = (int)rawData[0];
//remove group number from raw data
rawData = rawData.Skip(1).ToArray();
}
for (int i = 0; i < rawData.Count(); i += 2)
{
group.values.Add(new KeyValuePair<decimal, decimal>(rawData[i], rawData[i + 1]));
}
}
}
}
}
}
}
public class Group
{
public int id { get; set; }
public List<KeyValuePair<decimal, decimal>> values = new List<KeyValuePair<decimal, decimal>>();
}
}
我刚刚意识到这不是最新的版本。我道歉。这可能会更容易向我展示一个如何做到这一点的样本,而无需轮胎来修复我当前的代码。伙计!我讨厌这些简单的解决办法。我总是让事情变得更难。除了一些我必须处理的格式之外,这正是我想要的。谢谢当组号存在时,不能将行放在一起。请参阅其他答案中的OPs注释。这是一个比我的解决方案更重的解决方案,对于这个问题可能有点过火,但如果正则表达式比空格字符和回车符更复杂,那么它肯定是一个不错的选择+1正则表达式仅用于标题行,不用于数字。我想跟你走。你怎么认为?string[]header=input.Splitnew char[]{},StringSpitOptions.Remove EmptyEntries.ToArray;fips=标题[1];状态=标题[3];wfo=收割台[5];我也要试试jdweng的版本。谢谢你们两位。@jdweng-所以我今天晚上在用你们的代码,我一辈子都不明白为什么它不起作用。直到我运行它,我才发现错误。在更仔细地查看数据之后,我意识到,通过这个95k行文件,数据并不完全相同。我看到的是90000FLTBW 10 29.141 29.139-83.035-83.038 29.139-83.035 29.139-83.035 29.139-83.035 8 29.141 29.141-83.036-83.036 29.141-83.036在“TBW”之后的“10”和在-83.035之后的“8”由于没有更好的术语,是子集。因此,我需要的是以下90000FLTBW 10 29.141 29.139-83.035-83.038 29.139-83.035 29.139-83.035和90000FLTBW 8 29.141 29.141-83.036-83.036 29.141-83.036。跟着我?你能帮我做这个吗?