Monday, 13 May 2013

Stumped by range

Today at $work we can across the following in someone's perl script

  if (/\Q$start/x../\Q$end/x) {print q{match};}

This rather stumped all of us from $boss down. Between us, we have over 25 years worth of perl experience, and no-one had seen this before. What is the range operator doing between 2 regexes?

It turns out, that we can use this to loop over (for example) lines in a file, and when $start is seen, start printing out until $end is seen. Then reset and finish looping.

A google search brought up the following page

http://perlmeme.org/faqs/file_io/middle_of_a_file.html

Interestingly (although it is probably the right way to do it), it only keeps a track of whether you have seen $start once, and $end once (before a 'reset') so if $start is there twice before $end, it only finds the first $end, and stops 'matching'. ie:



 foo       no_match
 $start    match
 foo       match
 foo       match
 $start    match
 foo       match
 $end      match
 foo       no_match
 $end      no_match
 $start    match
 foo       match
 foo       match
 $end      match
 foo       no_match



Whilst we worked this out (quicker with a hint from a comment), I think we universally decided that it wasn't particularly readable. However, I think my first ever production script probably would have been a bit shorter had I used it back then :)

I'll leave the merits of this down to the reader. Personally, I don't know how useful I'd find it, but it might help someone out there. Hello to you if you are that person!

(Hopefully, I'll remember this post next time I see this!)