MacUsers
MacUsers

Reputation: 2241

Ruby RegEx/pattern-match for exact word/string matching

Got a quick question: I have a file like this:

ip-10-0-12-84.eu-west-1.compute.internal, master, instnum=1, Running
.....
.....
ip-10-0-26-118.eu-west-1.compute.internal, master_rabbit, instnum=4, Running
ip-10-0-26-116.eu-west-1.compute.internal, master_rabbit, instnum=5, Running
.....
ip-10-0-26-68.eu-west-1.compute.internal, sql_master, instnum=9, Running
ip-10-0-13-244.eu-west-1.compute.internal, nat, instnum=2, Running

My goal is to read the file, skipping comments (starts with #), empty/blank lines and the lines with nat or master in it. I tried this:

open('/tmp/runnings.txt').each do |line|
    next if line =~ /(^\s*(#|$)|nat|master)/

which is almost working but it also eliminates the lines with master_rabbit and sql_master in it. How can I pick only master and not the any other combination of that? Can it done in the same line? Cheers!!

Upvotes: 4

Views: 2432

Answers (3)

hirolau
hirolau

Reputation: 13921

I feel this is not a place where the problem should be solved with a regexp. Sure you can get one to work for now, but it will be hard to understand later and harder to edit if you get new keywords to exclude.

I like this way of solving the problem:

FILE_PATH = '/tmp/runnings.txt'
keywords  = ['nat', 'master']
empty_lines_and_comments     = ->x{ x.chomp.empty? or x.start_with?('#') }
lines_containing_bad_keyword = ->x{ keywords.include? x[1] } # Keywords at index 1

data = File.readlines(FILE_PATH)
           .reject(&empty_lines_and_comments)
           .map{|line| line.chomp.split(', ')}
           .reject(&lines_containing_bad_keyword)

Upvotes: 1

sawa
sawa

Reputation: 168269

open("/tmp/runnings.txt").each_line
.grep(/\A(?!\s*#)(?!.*\bnat\b)(?!.*\bmaster\b).*\S/) do |line|
  ...
end

Upvotes: 1

Tim Pietzcker
Tim Pietzcker

Reputation: 336478

Word boundary anchors can help here:

/^\s*(#|$)|\b(nat|master)\b/

Upvotes: 6

Related Questions