I seem to remember some discussion about regexps recently, including Perl
regexps versus Ruby regexps.
I am actually in favour of Ruby regexps pretty much as they are, but I have
one gripe: it doesn’t seem to be possible to make “$” match “end of string”
rather than “before a newline”.
I wrote a regexp which I thought would match trailing \n’s in a string:
a.gsub!(/\n+$/,'')
This is pretty standard stuff in Perl:
perl -e '$a="abc\ndef\n"; $a =~ s/\n+$//; print "<$a>\n";'
But it doesn’t work in Ruby. Adding /m doesn’t help either. It took a fair
bit of head-scratching and digging around for me to discover that to match
the end of a string you must use ‘\z’.
In Perl, I believe “^” and “$” match the start and end of the string only,
unless you have multiline mode enabled.
A bit of playing around shows:
^ matches $ matches . matches
--------- --------- ---------
Ruby // start of string end of string any char except \n
or after \n or before \n
[note]
Ruby //m start of string end of string any char
or after \n or before \n
Perl // start of string end of string any char except \n
Perl //m start of string end of string any char except \n
or after \n or before \n
Perl //s start of string end of string any char
Perl //ms start or string end of string any char
or after \n or before \n
So it looks like Ruby’s “normal” mode is like Perl’s “multiline” mode, and
there is no way to get Perl’s “normal” mode in Ruby. Ruby’s “multiline” mode
is really Perl’s “/ms” mode
[note]
Actually, that’s not even true. Perl’s $ will match end-of-string after a
newline even in multiline mode:
$ perl -e ‘$a=“abc\n”; $a =~ s/c\n$//m; print “<$a>\n”;’
But Ruby can’t.
$ ruby -e ‘a=“abc\n”; a.gsub!(/c\n$/,“”); puts “<#{a}>”;’
<abc
This means the description “$ matches end of string or before \n” is wrong
for Ruby. In fact, I’m not sure what exactly $ matches. Can anybody give
me a description of what $ matches in Ruby?
I think this difference in behaviour is unfortunate, as I consider that “^”
and “$” are part of the lowest-common-denominator of regexp behaviour which
ought to be reasonably portable.
Regards,
Brian.