Reading particular text from a txt file

Eric C. wrote in post #1050315:

This is the code you want:

str = File.open("status.txt") { |f| f.read }
m = /^CRP\+TYH\+(\d+)/.match(str)
puts m[1]

That code has several issues:

1. It will break (throw an exception) if the string is not found in the
file because it does
not check whether m is non nil.
2. File.read() is a much simpler way to read the whole file at once than
File.open(...){|f| f.read}.
3. It is inefficient because it reads in the whole file just to extract
a portion of the file.
4. Even worse, it will break for large files.
5. It does more IO than necessary because it always reads the whole
file.
6. Logic is not encapsulated in a method which hinders reuse.

Compare that to my solution:

def r(f)
  File.foreach f do |line|
    match = line[/^CRP\+TYH\+(\d+)/, 1] and return match
  end

  nil
end

The file is processed line by line (but still IO uses buffering
underneath for efficiency). Reading is stopped as soon as the data is
found. It won't break for large files.

We can even generalize the approach

def find_first_in_file(file, regexp, group = 1)
  File.foreach file do |line|
    match = regexp.match(line) and return match[group] || match[0]
  end

  nil
end

This will return the first match and if the regexp has a capturing group
it will return the capture of the first group. We would use it like
this

data = find_first_file("myfile.txt", /^CRP\+TYH\+(\d+)/)

Kind regards

robert

ยทยทยท

--
Posted via http://www.ruby-forum.com/\.