19

I've been teaching myself Ruby and for a certain problem I'm trying to solve I notice a lot of people are using =~ and /\ in their code. I'm not really sure how they work and would just like an explanation. For example I was looking at someones code for this Pig Latin translator and this is the first time I'm seeing these being used.

def piglatin(word)
   if word =~ (/\A[aeiou]/i)
      word = word + 'ay'
   elsif word =~ (/\A[^aeiou]/i)
      match = /\A[^aeiou]/i.match(word)
      word = match.post_match + match.to_s + 'ay'
   end
word
end

I'm just confused about the /\ slashes and the =~

St3
  • 401
  • 1
  • 3
  • 12
  • 2
    Here's the doc for the method [Regexp#=~](http://www.ruby-doc.org/core-2.1.3/Regexp.html#method-i-3D-7E) and it's `\A`, not `\/\`. where `\\` escapes the following character, but what you need to do is read up on "regular expressions". It will be covered in any book on Ruby and at zillions of URLs. It's a big subject. – Cary Swoveland Nov 14 '14 at 20:31
  • There's a great answer[here](https://stackoverflow.com/a/5781400/5783745) with some examples. – stevec Jan 18 '22 at 11:23

4 Answers4

38

=~ is known as the "match operator" and can be used to match a string against a regular expression.

The /\ is actually part of two separate things. / denotes the start of a regular expression and \A is known as an "anchor" and is saying "match from the beginning of the string."

edit: This is a link to the documentation that should help you understand more code like you posted.

thank you to Wayne Conrad for a correction on '/\'

Community
  • 1
  • 1
  • Good - I would just the explaination that using forward slashes `/apple/` creates a regular expression. Using backslashes in the expression escapes the character `/\./` matches an actual dot character instead of any character. – max Nov 14 '14 at 20:33
  • 1
    @papirtiger Good points, but `\A` and `\.` are different cases and would lead down the path of explaining regex more poorly than the reference doc. –  Nov 14 '14 at 20:36
  • For those unfamiliar with regular expressions, [Rubular](http://rubular.com/) is a site where you can learn more about them and try them out in the browser. It even has a handy cheat sheet. – tadman Nov 14 '14 at 20:41
  • 3
    @tadman yeah, Rubular is a great resource, but I'd definitely suggest new Rubyists check out the official documentation as it covers things like bracket expressions and how to get started. –  Nov 14 '14 at 20:44
  • The [Regexp documentation](http://www.ruby-doc.org/core-2.1.5/Regexp.html) is a multiple must-read. There is a lot to learn about regexp, and it takes a while to digest it all and learn how to use regular expressions... especially the part about not trying to use them for everything. – the Tin Man Nov 14 '14 at 21:54
7

=~ is Ruby's pattern-matching operator.

It matches a regular expression on the left to a string on the right.

If a match is found, the index of first match in string is returned. If the string cannot be found, nil will be returned.

/abc/ =~ "abcdef"

In this case, the expression returns 0, because that is the index of the first match of "abc" in the string.

/xyz/ =~ "abcdef"

returns nil because "xyz" cannot be found anywhere in the string.

As for /\:

/     Defines the start and end of a regular expression
\     References a regular expression

For example:

\d => Matches all digits
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Darkmouse
  • 1,941
  • 4
  • 28
  • 52
2

The equal-tilde operator in Ruby is the “match” operator. It take an regular expression on the left hand side and the string to match on the right hand side. The expression:

/or/ =~ “Hello World”

will return 7 because a match is found on index 7 of the string. The index starts at 0.

The expression:

/abc/ =~ “Hello World”

will return nil because there is no match.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Kevin Austin
  • 184
  • 7
2

The use of /\A and =~ aside, that code is not written well, so don't emulate it. This is a bit more Ruby-like:

def piglatin(word)
  if word[/\A[aeiou]/i]
    word + 'ay'
  else
    word[1..-1] + word[0] + 'ay'
  end
end

piglatin('apple')   # => "appleay"
piglatin('banana')  # => "ananabay"

For this purpose, ^ would have worked as well as \A as they're both "beginning of..." anchors. These are from the Anchors definitions:

  • ^ - Matches beginning of line
  • \A - Matches beginning of string.
the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • So just to be clear `if word[/\A[aeiou]/i]` is saying if the string matches either a, e, i, o, or u in the start of the string then return the word + ay. the `/i` is so the case doesn't matter. For some reason I thought `[aeiou]` had to be like `["a", "e", "i", "o", "u"]` – St3 Nov 17 '14 at 19:29