Ruby regex lookarounds?

In Programming Ruby(1st Ed), it says:

The match operators return the character position at which the match
occurred. They also have the side effect of setting a whole load of Ruby
variables. $& receives the part of the string that was matched by the
pattern, $` receives the part of the string that preceded the match, and
$’ receives the string after the match…

The match also sets the thread-global variables $~ and $1 through $9.
The variable $~ is a MatchData object (described beginning on page 336)
that holds everything you might want to know about the match. $1 and so
on hold the values of parts of the match.

Here is an example:

irb(main):009:0> “abc” =~ /(a)(b)/
=> 0
irb(main):010:0> $&
=> “ab”
irb(main):011:0> $1
=> “a”
irb(main):012:0> $2
=> “b”

Now and example with a lookbehind:

irb(main):013:0> “abc” =~ /(?:ab)©/
=> 0
irb(main):014:0> $&
=> “abc”
irb(main):015:0> $1
=> “c”

Isn’t that output inconsistent? If Ruby wants to say that the regex
matches the whole string, then shouldn’t $1 be ‘ab’. I know that
lookarounds shouldn’t be considered part of the match–they are just
assertions, but Ruby’s $& variable doesn’t seem to respect that.

Isn’t that output inconsistent? If Ruby wants to say that the regex
matches the whole string, then shouldn’t $1 be ‘ab’. I know that
lookarounds shouldn’t be considered part of the match–they are just
assertions, but Ruby’s $& variable doesn’t seem to respect that.

I see what’s going on. (?:ab) is not a grouping: (?: and ) do not form a
grouping that gets a $ variable. If I write it as (?:(ab)), then ab is
a grouping:

irb(main):021:0> “abc” =~ /(?:(ab))©/
=> 0
irb(main):022:0> $&
=> “abc”
irb(main):023:0> $1
=> “ab”
irb(main):024:0> $2
=> “c”
irb(main):025:0>

It still seems a little strange that $& contains the lookaround.

Hi,

The syntax (?:re) isn’t a lookbehind. It is a grouping form like (re)
but without capture. So (?:(re)) is the same as (re). Off course, you
could write something like (?:a(bc)), and you will get “bc” in $1, and
not “abc”.

On Mar 14, 2007, at 7:30 AM, come wrote:

The syntax (?:re) isn’t a lookbehind.

Exactly. And just to make this description complete, Ruby 1.8 does
not support lookbehind.

James Edward G. II

come wrote:

Hi,

The syntax (?:re) isn’t a lookbehind. It is a grouping form like (re)
but without capture.

I don’t understand the distinction.

Non-capturing grouping is exactly what it sounds like, a group that
doesn’t
capture whatever it matches, but still consumes. So…

#non capturing group
irb(main):009:0> “1234” =~ /(?:1234)/
=> 0
irb(main):010:0> $1
=> nil

#capturing group
irb(main):011:0> “1234” =~ /(1234)/
=> 0
irb(main):012:0> $1
=> “1234”

Lookahead and lookbehind peek ahead or behind without consuming what
they
match.

MBL

On 18.03.2007 11:42, 7stud 7stud wrote:

come wrote:

The syntax (?:re) isn’t a lookbehind. It is a grouping form like (re)
but without capture.

I don’t understand the distinction.

Lookahead and -behind do not consume characters while non capturing
groups do.

robert