9

Ruby 1.8.7. I'm using a regex with a ^ to match a pattern at the start of the string. The problem is that if the pattern is found at the start of any line in the string it still matches. This is the behaviour I would expect if I were using the 'm' modifier but I'm not:

$ irb
irb(main):001:0> str = "hello\ngoodbye"
=> "hello\ngoodbye"
irb(main):002:0> puts str
hello
goodbye
=> nil
irb(main):004:0> str =~ /^goodbye/
=> 6

What am I doing wrong here?

SteveRawlinson
  • 755
  • 2
  • 6
  • 12

4 Answers4

23
  • start of the line: ^
  • end of the line: $
  • start of the string: \A
  • end of the string: \z
Matt Briggs
  • 38,679
  • 14
  • 86
  • 125
17

Use \A instead of ^.

Ruby regex reference: http://www.zenspider.com/ruby/quickref.html#regexen

overthink
  • 22,610
  • 3
  • 63
  • 68
noodl
  • 16,411
  • 2
  • 52
  • 54
12

Your confusion is justified. In most regex flavors, ^ is equivalent to \A and $ is equivalent to \Z by default, and you have to set the "multiline" flag to make them take on their other meanings (i.e. line boundaries). In Ruby, ^ and $ always match at line boundaries.

To add to the confusion, Ruby has something it calls "multiline" mode, but it's really what everybody else calls "single-line" or "DOTALL" mode: it changes the meaning of the . metacharacter, allowing it to match line-separator characters (e.g. \r, \n) as well as all other characters.

Alan Moore
  • 68,531
  • 11
  • 88
  • 149
  • Which regex flavors have the behavior you describe? – Wayne Conrad Nov 23 '10 at 16:32
  • 1
    @Wayne: All the other Perl-derivative flavors work that way: Perl, PHP, Python, JavaScript, Java, .NET... If it has a "multiline" mode, that's what it means: `^` becomes "start of line" and `$` becomes "end of line". I'm not saying Ruby's approach is wrong, BTW; I just wish they hadn't mixed up the names like they did. The only flavor that really gets it right is Perl 6/Parrot, which eliminates "multiline" *and* "single-line" modes. – Alan Moore Nov 23 '10 at 18:53
  • 1
    Yes, I'm used to regex in C and Perl which use ^ in the same way Ruby uses \A. I thought the C regex library was the 'definitive' one - clearly I was mistaken. Thanks for your answers. – SteveRawlinson Nov 25 '10 at 11:32
  • This answer has been added to the [Stack Overflow Regular Expression FAQ](http://stackoverflow.com/a/22944075/2736496), under "Modifiers". – aliteralmind Apr 10 '14 at 00:52
  • This is by far the best answer, as it also explains the confusion that will hit most programmers which learn ruby and who are already familiar with regex in other languages. – Mecki Mar 22 '20 at 13:15
2

"^" is the start of the line. To make what you want, you can split de string and test just the first line. But I think exist some better method.

str.split("\n")[0] =~ /^hello/
Guilherme Bernal
  • 8,060
  • 23
  • 40