Mohammad
Mohammad

Reputation: 1577

Reading double Numbers from a text file which contains string and number mixed

I have a file which contains Numbers and Texts. and I'm trying to read all numbers as double and put them in a one dimension double array.

In the file , some lines begin with Space. also some lines contain Two or Three numbers after each other. The file is creating from another app which i don't want to change its output format.

The data in the file is like blow and some lines begin with some space :

 110        ! R1
123.000753   ! Radian per s as R2
  600.0451  65     ! j/kg
 12000         ! 4 Number of iteration
 87.619    ! (min 20 and max 1000)

My code so far is :

 char[] splits = { ' ', '!' };
 var array = File.ReadAllLines(@"myfile.dat")
.SelectMany(linee => linee.Split(splits))
.Where(n => !string.IsNullOrWhiteSpace(n.ToString()))
.Select(n =>
 {
  double doub;
  bool suc = double.TryParse(n, out  doub);
  return new { doub, suc };
 }).Where( values=>values.suc).ToArray();

The problem is that my code also read numbers after ! in the descriptions like line 4 and line 5.

Array have to be like this :

110 , 123.000735 , 6000.0451 , 65 , 120000 , 87.619

But in my code is like this :

110 , 123.000735 , 6000.0451 , 65 , 120000 , 4 , 87.619 , 20 , 1000

Upvotes: 1

Views: 130

Answers (3)

Dour High Arch
Dour High Arch

Reputation: 21711

It's hard to give a general formula when given only a single example, but the following will work for your example:

return File.ReadLines(@"myfile.dat")
    .Where(s => !String.IsNullOrWhiteSpace(s))
    .Select(s => s.Substring(0, s.IndexOf('!')).Split(new [] {' '}, StringSplitOptions.RemoveEmptyEntries))
    .SelectMany(s => s)
    .Select(s => Double.Parse(s));

Upvotes: 1

Paulo Morgado
Paulo Morgado

Reputation: 14846

Here's an alternate solution using regular expressions:

var regex = new Regex(@"^(\s*(?<v>\d+(\.\d+)?)\s*)+\!.*$");

var query = from line in lines
            let match = regex.Match(line)
            where match.Success
            from @group in match.Groups.Cast<Group>()
            where @group.Name == "v"
            select double.Parse(@group.Value, NumberStyles.Float, CultureInfo.InvariantCulture);

Upvotes: 1

Anu Viswan
Anu Viswan

Reputation: 18155

One approach could be as following.

var lines = str.Split(new []{"!",Environment.NewLine},StringSplitOptions.RemoveEmptyEntries)
               .Where(x=> x.Split(new []{" "},StringSplitOptions.RemoveEmptyEntries).All(c=>double.TryParse(c, out _))).
               SelectMany(x=> x.Split(new []{" "},StringSplitOptions.RemoveEmptyEntries).Select(c=>double.Parse(c)));

Upvotes: 1

Related Questions