tags:

views:

60

answers:

3

The following code opens a text file does a little regex to match names and numbers. I do an IF so that I only match numbers greater than 0. When I try to puts the name and number, I only get the numbers and the name have become nil. If I puts the names (variable a) before the if statement, it is there. What am I doing wrong?

nf = File.open("textfile.txt")

nf.each do |b|
 a = b.match(/([\S]+)name([\S]+)/)
 c = b.match(/[0-9]+ numbers/)
 c = c.to_s.split(/ /)
 c = c[0].to_i
  if c > 0
   puts a
   puts c
  end 
 end

textfile looks like this:

My name is Mark
12432 numbers
My name is Joe
0 numbers

I want to be able to puts:
My name is Mark
12432 numbers

and not print out:
My name is Joe
0 numbers

Thanks in advance for your help

+2  A: 

Well there are four lines. On lines 1 and 3 there is a name, so a will not be nil. However c > 0 will be false and thus nothing will be printed.

On lines 2 and 4 there is no name, so a is nil.

Edit: Also /([\S]+)name([\S]+)/ will never actually match in your example file because "name" is surrounded by spaces (and \S means "not a space").

Edit2: Here's a solution using scan

File.read("textfile.txt").scan(/My name is (\w+)\n(\d+) numbers/) do |name, num|
  num = num.to_i
  if num > 0
    puts "Name: #{name}"
    puts "Number: #{num}"
  end
end
sepp2k
any suggestions on how to fix the code?
nomoreflash
@lovecode: Don't iterate by line. Iterate in groups of two lines, if you know the file is layed out that way. Or read the whole file into a string and use `scan` to find each occurence of name+number.
sepp2k
Thanks for the space tip, I made the change, but I still only get the numbers and the names are nil. Note that if I puts a (names) before the if statement I do get the names, but not after the if.
nomoreflash
Can you give me a quick example of the scan option you suggest?
nomoreflash
@lovetocode: There you go.
sepp2k
Thanks for your help
nomoreflash
A: 

The problem is that you are trying to match both name and numbers in the same line.

A quick script that works, tested in irb:

File.open("foo", "r") do |file|
  while name_line = file.gets
    if name_line =~ /\s+name\s+/
      number_line = file.gets # Here we read onto the next line
      if match = number_line.match(/(\d+) numbers/)
        # If matches, it will keep the number in the first capture group
        puts name_line, match[1] if match[1].to_i > 0
      end
    end
  end
end

Note that this will not work if two consecutive lines match "name" and the third one has "numbers", which may not be the case

Chubas
A: 
p=""
File.readlines("file").each do |line|
  num = line.split[0]
  if num.to_i > 0
    print "#{p}#{line}"
  else
    p=line
  end
end