【问题标题】:How to parse specific line in a text file in c#如何在c#中解析文本文件中的特定行
【发布时间】:2017-08-29 23:10:33
【问题描述】:

我需要解析文本文件中的特定行,其中以特定单词开头,如下图所示:

我只需要解析以“Level”开头的行,只提取“Row”和“Col”的值。 请注意,文本文件将包含 6 组此类数据,其中每组以

开头

---------------- 染色体 : # ------------------

请参阅以下示例:Sample

我需要将每个组的行和列保存在一个单独的列表中!!。 有没有办法做到这一点?

我尝试了以下方法:

public List<int[,]> getValuesFromTextFile(String filePath ) {

     IEnumerable<string> allLines = Enumerable.Empty<string>();

     List<int[,]> path = new List<int[,]>();

     int[,] item = new int[2,1];

    if (File.Exists(filePath))

        {
                    //Read all content of the files and store it to the list split with new line 
                    allLines = File.ReadLines(filePath);
        }
 
                    //all Level lines
                IEnumerable<string> levelLines = allLines.Where(d => d.StartsWith("Level", StringComparison.CurrentCultureIgnoreCase));
 
                foreach(string line in levelLines)

                {
                     string[] values= line.Split(':');//either space or tab or others as your file contain seperator  

                     for(int i=1; i <values.Length;i++)  {

                     string value = values[i];// skip index 0,it contains label, remaining are point data

                     if (i == 3) item[1,0] = Int32.Parse(value);

                     if (i == 5 && item[1,0] != null ) { item[0,0] = Int32.Parse(value);
                          path.Add(item);

                          }

                 }

        }



                return path;

        }

我在行(if (i == 3) item[1,0] = Int32.Parse(value);)收到以下错误:

输入字符串的格式不正确。

当我在这一行设置一个断点时,我看到字符串“value”的值等于 null!!。

当我添加一个断点来查看所有行列表内容时,我得到如下图:

上述方法需要分别解析每组关卡!!。

【问题讨论】:

  • 你的错误很明显。 value 不包含可以转换为 int 的字符串。设置一个断点,看看它是什么。
  • 你能放一个断点并发布你看到的内容吗?
  • 所以,你现在知道这个错误是从哪里来的
  • @L.B:我已经更新了我的问题。 . .
  • 我建议您改用正则表达式。请参阅 msdn.microsoft.com/en-us/library/… 以这种方式解析文本会更容易。

标签: c# parsing file-io text-parsing string-parsing


【解决方案1】:

Rose,你有两个问题。首先,将文本分成组,然后解析每一行。第二个可以使用正则表达式轻松完成,但我将使用 Json.Net 的 json 技巧 :)

int groupInx = 0;
var groupLines = File.ReadLines(@"d:\temp\a.txt")
                .GroupBy(x => x.Contains("Chromosome") ? ++groupInx : groupInx);

foreach(var group in groupLines)
{
    var lines = group.Skip(2) //skip ----- lines
                    .Select(x => JObject.Parse($"{{{x}}}"))
                    .ToList();

    //use a loop for each lines here
    int level = (int)lines[0]["Level"]; //for example
    int col = (int)lines[0]["Col"]; //for example

}

【讨论】:

  • 最后两行[0]是什么意思?
  • 只是为了显示每组第一行的内容。在那里写一个循环并使用它的索引,如i
  • 当然,我在答案中发布了它的链接。忘记我的回答。看来这场对话会永远持续下去。
  • 如何将此引用添加到我的解决方案中,我已下载但无法使用或将其安装到我的解决方案中(VS 2010)
  • @Rose 打开 zip 文件然后查看解决方案资源管理器树,右键单击 references,选择 add referencebrowse我>。 (你也可以使用Manage nuget packages来做同样的事情,只需搜索Json.Net的形式并安装它)
【解决方案2】:

您可以使用命名组 Regex 来解析行并构建记录列表。

void Main()
{
    var file = File.ReadLines(@"C:\TreeParser.txt");

    var groupRegex = new Regex(@"Chromosome : (?<Chromosome>[0-9])");
    var recordRegex = new Regex(@"Level : '(?<Level>[0-9])', Row : '(?<Row>[0-9])', Col : '(?<Col>[0-9])'");

    var groups = new List<Group>();

    foreach (var line in file)
    {
        var groupMatch = groupRegex.Match(line);
        if (groupMatch.Success)
        {
            groups.Add(new Group
            {
                Chromosome = int.Parse(groupMatch.Groups["Chromosome"].Value),
                Records = new List<Record>()
            });
        }

        var recordMatch = recordRegex.Match(line);
        if (!recordMatch.Success)
        {
            // No match was found
            continue;
        }

        var level = new Record
        {
            Level = int.Parse(recordMatch.Groups["Level"].Value),
            Row = int.Parse(recordMatch.Groups["Row"].Value),
            Col = int.Parse(recordMatch.Groups["Col"].Value)
        };

        groups.Last().Records.Add(level);
    }

    // groups now contains a list of each section from the file with a list of records
}

public class Record
{
    public int Level { get; set; }
    public int Row { get; set; }
    public int Col { get; set; }
}

public class Group
{
    public int Chromosome { get; set; }
    public List<Record> Records { get; set; }
}

【讨论】:

  • 查看问题The above method needs to parse each group of levels separately!!.
  • 我们需要在示例文本文件中有 6 个列表
  • @Rose 我更新了我的答案,将记录分成 6 组。
  • @Connor :您的回答给出了不完整的结果 :: 请在此处查看以下示例:dropbox.com/sh/j7s1n5wk6d91oqi/AADtj8SE4u2LbPmrDNgDUeIZa?dl=0 ---> 非常感谢。你能帮我完成这个问题吗?! :)
  • @Connor:请检查recordRegex,因为并非所有记录都存储在某些组中!!。我试图猜测问题出在哪里,但我不能,因为我不太喜欢正则表达式!!。
【解决方案3】:

这个怎么样:

   List<RowAndCol> lstrc = new List<RowAndCol>();
    private void Form1_Load(object sender, EventArgs e)
    {

        var file = File.ReadLines("E:\\SAMPLE_FILE\\sample.txt");

        var getList = (from f in file.ToList() where f.Contains("Level") || f.Contains("Chromosome") select f).ToList();
        int cnt = 1;

        string chr = string.Empty;
            foreach (var fl in getList.ToList())
            {

                RowAndCol rl = new RowAndCol();
                if (fl.Contains("Level"))
                {
                    String[] s = fl.Split(',');
                    String[] rowValue = s[1].Trim().Split(':');
                    String[] colValue = s[2].Trim().Split(':');

                    rl.Chromosome = chr;
                    rl.rownum = cnt;
                    rl.rowtext = "Row";
                    rl.coltext = "Col";
                    rl.row = rowValue[1].ToString();
                    rl.col = colValue[1].ToString();

                    cnt += 1;
                }
                else
                {
                    chr = fl.ToString();
                }

                lstrc.Add(rl);
            }
            cnt = 1;
    }
    public class RowAndCol
    {
        public int rownum { get; set; }
        public string Chromosome { get; set; }
        public String rowtext { get; set; }
        public String coltext { get; set; }
        public String row { get;set; }
        public String col { get; set; }
    }

【讨论】:

  • 在发布答案之前没有人再阅读以前的 cmets 了吗?团体呢?
  • 我忘记了群组.. 稍后会更新它感谢@L.B
  • 就我分析的示例文本内容而言,该组是按升序排列的。更新了上面的答案
  • 每一行中的每一组染色体都有自己的计数。
  • 你不觉得 lambda 符号有时更容易吗?对于 ex 使用 file.Where(f=&gt; f.Contains("Level")) 而不是 from f in file.ToList() where f.Contains("Level") select f
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多