Avatar of Skale
Skale
 asked on

How to process a txt file for parsing with a function in C#

Hello,

I've a txt file like below and i'd like to get some informations from it with a function but need a expert help for parsing.

  139 142    :No. nodes, No. modes:
 part                                            
      new modal                                 =                                                                                 
           refmod                                
                mass                            = 2.000D+03
                nelastq                         = 142
                ielastq (   1)                  = Eigen Mode    7 :        3.895 Hz
                ielastq (   2)                  = Eigen Mode    8 :        8.914 Hz
                ielastq (   3)                  = Eigen Mode    9 :       10.455 Hz
                ielastq (   4)                  = Eigen Mode   10 :       10.633 Hz
                ielastq (   5)                  = Eigen Mode   11 :       14.134 Hz
                ielastq (   6)                  = Eigen Mode   12 :       14.230 Hz
                ielastq (   7)                  = Eigen Mode   13 :       14.839 Hz
                ielastq (   8)                  = Eigen Mode   14 :       15.543 Hz
                ielastq (   9)                  = Eigen Mode   15 :       16.810 Hz
                ielastq (  10)                  = Eigen Mode   16 :       16.921 Hz
                ielastq (  11)                  = Eigen Mode   17 :       17.858 Hz
                ielastq (  12)                  = Eigen Mode   18 :       18.822 Hz
                ielastq (  13)                  = Eigen Mode   19 :       19.006 Hz
                ielastq (  14)                  = Eigen Mode   20 :       19.335 Hz
                ielastq (  15)                  = Eigen Mode   21 :       19.430 Hz
                ielastq (  16)                  = IRM           1 :       59.876 Hz
                ielastq (  17)                  = IRM           2 :       60.495 Hz
                ielastq (  18)                  = IRM           3 :       61.735 Hz
                ielastq (  19)                  = IRM           4 :       64.041 Hz
                ielastq (  20)                  = IRM           5 :       67.065 Hz
                ielastq (  21)                  = IRM           6 :       67.663 Hz
                ielastq (  22)                  = IRM           7 :       69.528 Hz
           end refmod   
	   
			Some Text Data
			.
			.
			.     

Open in new window

           

I'd like to get informations from  ielastq (   *id*) rows.

If there's a function like

public static string[] GetIElastiq(int id)
{
// some code here
}

Open in new window


if i wrote id 10 that function i'd like to get result as [ {Eigen Mode}, {16}, {16.921} ]

It'll found the row:          
   ielastq (  10)                  = Eigen Mode   16 :       16.921 Hz

Open in new window


and parse for me.

The values always between "refmod" and "end refmod" so Textreader only can focus this region.

Any help would be very great!!

Thank you.
C#

Avatar of undefined
Last Comment
ste5an

8/22/2022 - Mon
ste5an

What have you so far?

Just "loop" over the input file / stream by reading line for line. Seems like it is sufficient to look for lines with "ielastq". Parsing can be done here by splitting the line using fixed positions with SubString.
it_saige

Something like this should suffice:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace EE_Q29167461
{
    class Program
    {
        static void Main(string[] args)
        {
            var contents = System.IO.File.ReadAllLines($"{typeof(Program).Namespace}.txt").Where(x => x.IndexOf("ielastq", StringComparison.OrdinalIgnoreCase) > -1);
            var matches = contents.GetIElastiqById(10);
            foreach (var match in matches)
            {
                Console.WriteLine(match);
            }
            Console.ReadLine();
        }
    }

    static class Extensions
    {
        public static IEnumerable<string> GetIElastiqById(this IEnumerable<string> data, int id)
        {
            var parameter = default(int);
            return data.Where(x => 
                Regex.Match(x, @"\(([^)]+)\)").Groups.Count > 1 && 
                int.TryParse(Regex.Match(x, @"\(([^)]+)\)").Groups[1].Value.Trim(), out parameter) && 
                parameter == id
            );
        }
    }
}

Open in new window

Produces the following output -Capture.PNG-saige-
Skale

ASKER
it_saige, thank you so much :) It fits very well.
This is the best money I have ever spent. I cannot not tell you how many times these folks have saved my bacon. I learn so much from the contributors.
rwheeler23
ste5an

Reading the entire file is normally slower (lines > 255)..

namespace ConsoleCS
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;

    public class Program
    {
        public static void Main(string[] args)
        {
            IElastq ielastq = new IElastq(@"c:\temp\data.txt");
            var dataPoint = ielastq[10];
            Console.WriteLine(dataPoint);

            Console.WriteLine("\nDone.");
            Console.ReadLine();
        }
    }

    public class IElastq
    {
        private Dictionary<int, Tuple<string, string, double>> iElastq = new Dictionary<int, Tuple<string, string, double>>();

        public Tuple<string, string, double> this[int i]
        {
            get
            {
                return this.iElastq[i];
            }
        }

        public IElastq(string filename)
        {
            using (StreamReader file = new StreamReader(filename))
            {
                string line;
                bool inRefMod = false;
                while ((line = file.ReadLine()) != null)
                {
                    line = line.Trim();
                    if (inRefMod)
                    {
                        if (line.StartsWith("ielastq"))
                        {
                            int number = int.Parse(line.Substring(9, 4));
                            string description = line.Substring(33, 17).Trim();
                            double frequency = double.Parse(line.Substring(51, 14), new CultureInfo("en-US"));
                            string unit = line.Substring(65, line.Length - 65);
                            this.iElastq.Add(number, new Tuple<string, string, double>(description, unit, frequency));
                        }

                        if (line.Equals("end refmod"))
                        {
                            break;
                        }
                    }

                    if (line.Equals("refmod"))
                    {
                        inRefMod = true;
                    }
                }
            }
        }
    }
}

Open in new window


Capture.PNG
Skale

ASKER
@ste5an,

Thanks for the reply, it's not guaranteed the locations will be same so substring may not work in some cases. Also is tuple useful? I think it's making more slower the application.

@it_saige
Is'it possible to limit readed section to between "refmod" and "end refmod" ?
Skale

ASKER
Also i tried to parse output string but didnt succeded how is it possible to get single results from output string

                ielastq (  10)                  = Eigen Mode   16 :       16.921 Hz

Open in new window

Like below;
				Eigen Mode
				16
				16.921

Open in new window

⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
ASKER CERTIFIED SOLUTION
ste5an

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
GET A PERSONALIZED SOLUTION
Ask your own question & get feedback from real experts
Find out why thousands trust the EE community with their toughest problems.
SOLUTION
it_saige

THIS SOLUTION ONLY AVAILABLE TO MEMBERS.
View this solution by signing up for a free trial.
Members can start a 7-Day free trial and enjoy unlimited access to the platform.
See Pricing Options
Start Free Trial
⚡ FREE TRIAL OFFER
Try out a week of full access for free.
Find out why thousands trust the EE community with their toughest problems.
Skale

ASKER
ste5an, it_saige,

Thank you so much this is the ever never best solution for my case. Thanks a lot again.
Skale

ASKER
Maybe it's a basic question but i'd like to know is this IElastq objects need to release ? Are they keep in memory when procedure ends? I mean their lifetime.
ste5an

In short: .NET manages the life time of objects at runime. When an object is no longer references it is free during the next run of the garbage collector.
For further details and exceptions see Fundamentals of garbage collection.
Your help has saved me hundreds of hours of internet surfing.
fblack61