Instead of opening, reading and closing the file all the time, you should read it once and then just use the string multiple times (this will also safe time and bandwidth).
img = f.read.scan(/<img/).length
This won't necessarily give you an accurate count of <img>
tags. For example it will also count occurrences of <img
that appear in comments or in scripts. If you want an accurate count, you should use an HTML parsing library. (Same applies to when you do the same thing to the other tags of course).
Also, as helpfully pointed out by Christopher Creutzig, in case of the a-tag your regex will also count <address
tags or anything else that starts with a
(and if there should ever be HTML tags whose name start with div
or h1
etc., those will be miscounted as well). This can be fixed by adding a \b
after the tag as Christopher suggested (so that the tag name can't be followed by another word-character). Using a proper HTML parsing library is still your best option though.
f.close
No need to returnclose the stream when using open
with a block. The stream will be closed automatically when the block ends.
I'd also recommend to put the tag-counting code into a method. This way you don't need to repeat the same code for each tag.
If you're okay with changing the output, so that it's uniform for all tags, you might even turn the whole thing into a loop, so there's no repetition at all. Something like this:
%w(img a div h1 form).each do |tag|
count = contents.scan(/<#{tag}\b/).length
puts "\t#{count} #{tag} tags"
end