如何提取包含标头的特定数据

本文关键字:数据 包含标 何提取 提取 | 更新日期: 2023-09-27 18:08:34

我有以下形式的数据,我想从中提取特定的信息:

    f
    hj
13:45
    A
    Cd
    F
    RT
14:10
    df
    gj
    G
.. goes on

假设,我想要Fgj之间的所有东西…有了时间戳,我该怎么做呢?我知道如何从F到gj的行,但我不知道如何包括时间戳也,我是非常新的c#。如有任何帮助,不胜感激。

输出应该类似于

13:45
    F
    RT
14:10
    df
    gj

EDIT:::

public static void search_HstrLog()
        {
            int counter = 0;
            string[] hist_Logs = Directory.GetFiles(@"c:'logs");
            string line;
            for (int i = 0; i < hist_Logs.Count(); i++)
            {
                StreamReader reader = new StreamReader(hist_Logs[i]);
                bool betweenStartAndEnd = false;
                while ((line = reader.ReadLine()) != null)
                {
                    {
                        {
                        string start = "RUN";
                        string end = "STOP";

                            if(line.Contains(start))
                                betweenStartAndEnd = true;
                            if (betweenStartAndEnd || isTimeStamp(line))
                                Console.WriteLine(line);
                            if(line.Contains(end))
                                betweenStartAndEnd = false;
                        }
                    }
                }
                reader.Close();
            }
        }
    public static bool isTimeStamp(string line)
    {
        return Regex.IsMatch(line, @"^'d{2}:'d{2} ?[a-z]*$");
    }

这就是我现在所拥有的,正则表达式已经轻微更新,因为时间戳行也可以包括文本,包括开始和结束项,例如,14:22 RUN

而且,这是数据看起来更具体准确的版本

14:22 RUN
     - abc
     - bfg
         dmf
            -rkc
15:33 
     dbv
        -fjh
        -fjs

所以在上面的例子中,如果开始是RUN,结束是fjh,那么结果将是…

 14:22 RUN
         - abc
         - bfg
             dmf
                -rkc
 15:33 
      dbv
         -fjh

如果start为bfg, end为dbv,输出为-

14:22 
    - bfg
         dmf
            -rkc
15:33 
     dbv

如何提取包含标头的特定数据

基本上你想要跟踪你是否在开始值和结束值之间,然后你需要一种方法来识别时间戳。这里我使用正则表达式,但您可以将其更改为其他任何内容,包括使用DateTime.ParseExact。如果你需要在比较前删除前后空白,你可能还需要使用string.Trim

string start = "F";
string end = "gj";
bool betweenStartAndEnd = false;
foreach(var line in lines)
{
    if(line == start)
        betweenStartAndEnd = true;
    if(betweenStartAndEnd || isTimeStamp(line))
        Console.WriteLine(line);
    if(line == end)
        betweenStartAndEnd = false;
}
public static bool isTimeStamp(string line)
{
    return Regex.IsMatch(line, @"^'d{2}:'d{2}$");
}

使用如下代码所示的状态机

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        enum State
        {
            FIND_START,
            COLLECT_DATA,
            STOP_COLLECTING
        }
        static void Main(string[] args)
        {
            string input =
                    "14:22 RUN'n" +
                         "- abc'n" +
                         "- bfg'n" +
                             "dmf'n" +
                                "-rkc'n" +
                    "15:33'n" +
                         "dbv'n" +
                            "-fjh'n" +
                            "-fjs'n";
            StringReader reader = new StringReader(input);
            string inputLine = "";
            string output = "";
            State state = State.FIND_START;
            while ((inputLine = reader.ReadLine()) != null)
            {
                switch (state)
                {
                    case State.FIND_START:
                        if (inputLine.Contains("RUN"))
                        {
                            output += inputLine + "'n";
                            state = State.COLLECT_DATA;
                        }
                        break;
                    case State.COLLECT_DATA:
                        output += inputLine + "'n";
                        if (inputLine == "dbv") state = State.STOP_COLLECTING;
                        break;
                    case State.STOP_COLLECTING:
                        break;
                }
            }
        }
    }
}