C# 使用流读取器将多行合并为一个字符串

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

我有一个大小适中的文件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   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。跟着我?你能帮我做这个吗?