2

I'm going through a file line by line and I want to check if that line contains any element from an array. for instance if I have:

myArray = ["cat", "dog", "fish"]

and the current line said:

I love my pet dog

The output would say

Found a line containing array string

Here's what I have but it doesn't work.

myArray = ["cat", "dog", "fish"]
File.open('file.txt').each_line { |line|
  puts "Found a line containing array string" if line =~ myArray  #need to fix this logic
}

I've tried include? and any? but don't know if I'm using them right.

UPDATE:: An important part i left out. I need exact matches! so i don't want the statement to return true if it isn't exact. For instance- if my line says "I love my pet doggie" this statement should return false since "dog" is in the array. Not "Doggie"

My mistake on the poor clarification

Jaron Bradley
  • 1,079
  • 3
  • 16
  • 24

4 Answers4

3

You have to check each string in the array separately, and use \b to match word boundaries to ensure you only get whole words:

strings = ["cat", "dog", "fish"].map { |s| Regexp.quote(s) }

File.open('file.txt').each_line do |line|
  strings.each do |string|
    puts "Found a line containing array string" if line =~ /\b#{string}\b/
  end
end

Alternatively build a Regex:

strings = ["cat", "dog", "fish"].map { |s| Regexp.quote(s) }
pattern = /\b(#{strings.join('|')})\b/

File.open('file.txt').each_line do |line|
  puts "Found a line containing array string" if line =~ pattern
end

Calling Regexp.quote prevents characters that have meaning in regular expressions from having an unexpected effect.

Andrew Marshall
  • 95,083
  • 20
  • 220
  • 214
1

You could create a regex using your array

myArray = ["cat", "dog", "fish"]
File.open('file.txt').each_line { |line|
  puts "Found a line containing array string" if %r(#{myArray.join('|')}) === line
}
oldergod
  • 15,033
  • 7
  • 62
  • 88
0
arr = ['cat', 'dog', 'fish']

File.open('file.txt').each_line do |line|
  puts 'Found a line containing key word' if arr.any? { |e| line.include? e }
end

For detecting as word not as substring:

line =~ /(#{e}|.*\s#{e})([\s.,:;-].*|\n)/

Also there is an interesting solution:

arr = ['cat', 'dog', 'fish']

File.open('file.txt').each_line do |line|
  puts 'Found a line containing array string' if !(line.split(/[\s,.:;-]/) & arr).empty?
end
Danil Speransky
  • 29,891
  • 5
  • 68
  • 79
  • I think i tried this before and ran into this problem -- I want to match exact words. So if my line said "I love my pet doggie" wouldn't this still return true? Any idea's on how to modify this for an exact match? – Jaron Bradley Sep 10 '12 at 02:45
  • @JaronBradley You don't mention that in your question. You should update it to include that as that change invalidates every answer here. – Andrew Marshall Sep 10 '12 at 02:49
0
myArray = ["cat", "dog", "fish"]
File.open('file.txt').each_line { |line|
  puts "Found a line containing array string" if myArray.any? { |word| /.*#{word}.*/.match? line}
}

Code not tested

Ismael Abreu
  • 16,443
  • 6
  • 61
  • 75