2011-05-08 13 views
5

Hay algo misterioso para mí sobre el estado de escape de una barra invertida dentro de una sola cadena de literales literal como argumento de String#tr. ¿Puedes explicar el contraste entre los tres ejemplos a continuación? Particularmente no entiendo el segundo. Para evitar complicaciones, estoy usando 'd' aquí, que no cambia el significado cuando se escapa en comillas dobles ("\d" = "d").Estado de escape dentro de un literal de cadena como argumento de `String # tr`

'\\'.tr('\\', 'x')  #=> "x" 
'\\'.tr('\\d', 'x')  #=> "\\" 
'\\'.tr('\\\d', 'x') #=> "x" 
+0

Interesante. ¿Y por qué ''\\ rs'.tr (' \\ rs ',' x ')' devuelve '\\ xx' ?! Hubiera esperado un valor de retorno de 'xxx'. Y en el [ejemplo de documentación] (http://ruby-doc.org/core/classes/String.html#M001199) '" hello ".tr ('aeiou', '*')', '*' es más corto que 'aeiou', entonces ¿qué significa * If to_str es más corto que from_str, está acolchado con su último carácter * mean? ¿Es un error? ¿Es una mosca? ¿Es Superman? : D – Zabba

+0

@Zabba Significa que '" hello ".tr ('aeiou', '* #')' es lo mismo que '" hello ".tr ('aeiou', '* ####') '. : D – sawa

+0

Qué salida esperarías (¡no lo ejecutes todavía, por favor!), De ''\\ d'.tr (' \\ d ',' xx)'? No espero que lo que * no * dar .. – Zabba

Respuesta

9

Escapar en tr

El primer argumento de tr funciona como soporte de caracteres de agrupamiento en las expresiones regulares. Puede usar ^ al comienzo de la expresión para anular la coincidencia (reemplace cualquier cosa que no concuerde) y use p. Ej. a-f para que coincida con una gama de caracteres. Como tiene caracteres de control, también escapa internamente, por lo que puede usar - y ^ como caracteres literales.

print 'abcdef'.tr('b-e', 'x') # axxxxf 
print 'abcdef'.tr('b\-e', 'x') # axcdxf 

Escapar de Ruby cadenas comilla simple

Además, al utilizar comillas simples, Ruby trata de incluir la barra invertida cuando sea posible, es decir, cuando no se utiliza para escapar realidad otra barra invertida o una comilla simple.

# Single quotes 
print '\\' # \ 
print '\d' # \d 
print '\\d' # \d 
print '\\\d' # \\d 

# Double quotes 
print "\\" # \ 
print "\d" # d 
print "\\d" # \d 
print "\\\d" # \d 

Los ejemplos revisados ​​

Con todo esto en mente, echemos un vistazo a los ejemplos de nuevo.

'\\'.tr('\\', 'x')  #=> "x" 

La cadena definida como '\\' se convierte en la cadena literal \ porque la primera barra invertida se escapa el segundo. No hay sorpresas allí.

'\\'.tr('\\d', 'x')  #=> "\\" 

La cadena definida como '\\d' se convierte en la cadena literal \d. El motor tr, a su vez usa la barra diagonal inversa en la cadena literal para escapar del d. Resultado: tr reemplaza instancias de d con x.

'\\'.tr('\\\d', 'x') #=> "x" 

La cadena definida como '\\\d' se convierte en el literal \\d. Primero \\ se convierte en \. Entonces \d se convierte en \d, es decir, se conserva la barra diagonal inversa. (Este comportamiento particular es diferente de las cadenas dobles, donde la barra invertida se comieron vivo, dejando sólo una solitaria d)

La cadena literal \\d continuación, hace tr reemplazar todos los caracteres que son o bien una barra invertida o una d con la cadena de reemplazo .

+1

Gracias por la explicación. Bonito. – sawa

Cuestiones relacionadas