Link to home
Start Free TrialLog in
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.
Avatar of ste5an
ste5an
Flag of Germany image

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.
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 -User generated image-saige-
Avatar of Skale
Skale

ASKER

it_saige, thank you so much :) It fits very well.
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


User generated image
Avatar of 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" ?
Avatar of 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

ASKER CERTIFIED SOLUTION
Avatar of ste5an
ste5an
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Skale

ASKER

ste5an, it_saige,

Thank you so much this is the ever never best solution for my case. Thanks a lot again.
Avatar of 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.
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.