Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Regexp Interpolation / Character Class / Global Variable Syntax Clash?

Tags:

regex

ruby

Why does this error occur?

    Regexp.new("[#$]")
    # => SyntaxError: (irb):1: syntax error, unexpected $undefined
    # => Regexp.new("[#$]")
    #              ^
    # (irb):1: unterminated string meets end of file
    #     from ~/.rvm/rubies/ruby-1.9.3-p194/bin/irb:1:in `<main>'

This should describe the subset of strings consisting of either a single $ or #, literally. And, AFAIU Ruby's Regexp engine, # and $ don't need to be escaped inside a character class even though they're usually metacharacters.

I would guess from the error message that Ruby is trying to interpolate $ when it's hitting # within double-quotes, but...why? Ordering is important. The $ and # characters have multiple overloaded behaviors, so I'm at a loss about what's triggering this.

PS, FYI:

    /[#$]/
    # => SyntaxError: (irb):1: syntax error, unexpected $undefined
    /[$#]/
    # => /[$#]/
    Regexp.new '[$#]'
    # => /[$#]/
    Regexp.new '[#$]'
    # => /[#$]/
    Regexp.new "[#$]"
    # => SyntaxError: (irb):1: syntax error, unexpected $undefined
like image 486
pje Avatar asked May 23 '12 17:05

pje


1 Answers

The problem is not $, but #, as #... is usually used for variable expansion in double quoted strings. Like "#{x}".

But the thing is you can also expand global variables directly using #$global, and that explains your problem:

$global = "hello"
"#$global"
=> "hello"

So the solution is to escape either # or $, as this will break the string interpolation state machine out of it's effort to interpret the construct as an interpolation:

puts "\#$global"
=> #$global
puts "#\$global"
=> #$global

EDIT

And just to make it really clear :) The problem is not the Regexp, but you are trying to expand a global variable named $] when you type "#$]":

puts "#$]"
SyntaxError: (irb):22: syntax error, unexpected $undefined

To fix it you need to escape something:

puts "\#$]"
=> #$]
like image 106
Casper Avatar answered Dec 06 '22 15:12

Casper