2012-05-23 21 views
5

¿Por qué ocurre este error?Ruby Regexp Interpolation/Character Class/Global Variable Syntax Clash?

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>' 

Esto debería describir el subconjunto de cadenas que consta de un único $ o #, literalmente. Y, AFAIU Ruby's Regexp engine, # y $don't need to be escaped dentro de una clase de caracteres a pesar de que generalmente son metacaracteres.

Supongo por el mensaje de error que Ruby está tratando de interpolar $ cuando está golpeando # entre comillas dobles, pero ... ¿por qué? Ordenar es importante Los caracteres $ y # tienen múltiples comportamientos sobrecargados, por lo que no sé qué es lo que lo desencadena.

PS, FYI:

/[#$]/ 
    # => SyntaxError: (irb):1: syntax error, unexpected $undefined 
    /[$#]/ 
    # => /[$#]/ 
    Regexp.new '[$#]' 
    # => /[$#]/ 
    Regexp.new '[#$]' 
    # => /[#$]/ 
    Regexp.new "[#$]" 
    # => SyntaxError: (irb):1: syntax error, unexpected $undefined 
+0

posible duplicado de [Desconcertado por un simple expresión regular] (http://stackoverflow.com/questions/9493100/stumped-by-a-simple-regex) –

+0

http://books.google.ca/books?id=jcUbTcr5XWwC&pg=PA48&lpg=PA48&dq=ruby+global+variable+interpolation&source=bl&ots=fIDnyi9zjG&sig=BqcdRjtCnj3pj-PCtcMYh7UHS18&hl=en&sa=X&ei=Ci29T8IJgZOJArLYzewN&ved=0CFoQ6AEwAw#v=onepage&q=ruby % 20global% 20variable% 20interpolación & f = falso –

+0

@muistooshort: sí, tiene razón: ambas preguntas tienen la misma respuesta. – pje

Respuesta

7

El problema no es $, pero #, como #... se utiliza generalmente para la expansión de variables en cadenas entre comillas dobles. Me gusta "#{x}".

Pero la cosa es que también puede ampliar variables globales utilizando directamente #$global, y que explica su problema:

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

Así que la solución es escapar ya sea#o$, ya que esto se romperá la máquina de estado de interpolación de cuerdas fuera de su esfuerzo por interpretar la construcción como una interpolación:

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

EDITAR

Y para que quede muy claro :) El problema no es la Regexp, pero usted está tratando de expandir una variable global llamada $] cuando se escribe "#$]":

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

Fijar que tiene que escapar algo:

puts "\#$]" 
=> #$] 
+0

+1, pero ¿no podría resolver el problema cambiando las posiciones de los símbolos (es decir, '[$ #]')? No hablo fluidamente Ruby, pero de acuerdo con los documentos '#' se trata como un literal a menos que sea seguido por '{', '$', o '@'. –

+1

@ AlanMoore - Sí, eso es cierto, reordenar también lo resuelve. El OP también señaló esto, sin embargo, en su texto * "... ordenar es importante ..." *. – Casper

+0

No sé lo que se supone que significa, pero el orden de los caracteres en una clase de personaje no puede ser significativo (aparte de los que tienen significados especiales como '^' y '-', eso es). –