Reputation: 27
I am new to Ruby and working on how to read text files and check if the pattern matches or not. I am not not sure how to print the wrong lines.
For example, this is the text file:
id: 1 food: apple, banana
id: 2 food: orange
ids: 3 food: apple, banana
id: 4 food: hello, yellow
id: 5food: apple, banana
Reading the file
File.open(ARGV[0]) do |f1|
while line = f1.gets
pattern = /id[:] [[:digit:]]+ food[:] [a-z,]+/
puts line.scan(pattern)
end
This prints the following results
id: 1 food: apple, banana
id: 2 food: orange
id: 4 food: hello, yellow
But I want to print the wrong lines
ids: 3 food: apple, banana
id: 5food: apple, banana
I am not sure how do check if the pattern doesn't match then print the lines that are formatted incorrectly.
Upvotes: 0
Views: 230
Reputation: 110685
Suppose the file is read into the variable contents
:
contents =<<_
id: 1 food: apple, banana
id: 2 food: orange
ids: 3 food: apple, banana
id: 4 food: hello, yellow
id: 5food: apple, banana
_
If food:
is required, you could use the following regular expression.
r = /
\A # match beginning of string
id:\s+ # match "id:" followed by > 0 spaces
\d+\s+ # match > 0 digits followed by > 0 spaces
food:\s+ # match "food:" followed by > 0 spaces
[[:alpha:]]+ # match > 0 (uppercase or lowercase) letters
(?:,\s+[[:alpha:]]+) # match a comma, > 0 spaces, > 0 letters in a non-capture group
* # match > 0 instances of the aforementioned non-capture group
\n # match newline
\z # match end of string
/x # free-spacing regex definition mode
contents.each_line { |line| puts line if line !~ r }
prints
ids: 3 food: apple, banana
id: 5food: apple, banana
Upvotes: 1
Reputation: 30056
scan
returns an empty array if there are no matches. So you could do
File.open(ARGV[0]) do |f1|
while line = f1.gets
pattern = /id[:] [[:digit:]]+ synset[:] [a-z,]+/
puts line if line.scan(pattern).empty?
end
end
Another way, cleaner. You can use =~
method to see if a line match a pattern. And it returns the matching index if the pattern match or nil, if none matches.
File.open(ARGV[0]) do |f1|
while line = f1.gets
pattern = /id[:] [[:digit:]]+ synset[:] [a-z,]+/
puts line unless line =~ pattern
end
end
Upvotes: 1