Ruby regex qué significa el \ 1 para gsub

¿Qué hace el \ 1?

Por ejemplo

"foo bar bag".gsub(/(bar)/,'car\1') 

Creo que tiene algo que ver con el uso de paréntesis, pero no estoy seguro. ¿Podría alguien explicármelo? ¿Y puedes hacer cosas como \ 2? Si es así, ¿qué haría eso?

Cada elemento que rodee con paréntesis en la parte de búsqueda corresponderá a un número \1 , \2 , etc., en la parte de sustitución.

En su ejemplo, solo hay un elemento entre paréntesis, el elemento "(bar)" , por lo que en cualquier lugar donde coloque un \1 es donde se intercambiará la parte dentro del paréntesis. Puede colocar el \1 varias veces, lo que es útil si desea repetir ese elemento encontrado, por lo que podría escribir legítimamente car\1\1\1 y la "bar" se intercambiará tres veces.

No hay uso para \2 porque solo hay un elemento entre paréntesis. Sin embargo, si tiene (bar)(jar) , entonces \1 representaría "bar" y \2 representaría "jar" .

Incluso podrías hacer cosas como esta:

 \1\2\1\2\2\1 

que se convertiría en:

 barjarbarjarjarbar 

Aquí hay un ejemplo del mundo real donde esto es útil. Digamos que tienes una lista de nombres como esta:

 Jones, Tom Smith, Alan Smith, Dave Wilson, Bud 

y quieres cambiarlo a esto:

 Tom Jones Alan Smith Dave Smith Bud Wilson 

Podrías buscar:

 (.+), (.+) 

y reemplazar con:

 \2 \1 

También podría reemplazar con:

 \1: \2 \1 

Que se convertiría en:

 Jones: Tom Jones Smith: Alan Smith Smith: Dave Smith Wilson: Bud Wilson 

En términos generales, \N se reemplaza con el N-ésimo grupo especificado en la expresión regular. \1 hace referencia al primer grupo coincidente y el número máximo de grupos es 9.

Algunos ejemplos:

 # wrap every integer into brackets '1 2 34'.gsub(/(\d+)/, '[\1]') # => "[1] [2] [34]" # gsub with two groups: swap couples of integers '<1,2> <3,4>'.gsub(/(\d+),(\d+)/, '\2,\1') # => "<2,1> <4,3>" # you can reference the same group more than once '1 2 34'.gsub(/(\d+)/, '<\1,\1>') # => "<1,1> <2,2> <34,34>" # a slightly more complex example 'Jim Morrison'.sub(/([AZ])[az]+ ([AZ][az]+)/, '\2 \1.') # => "Morrison J." 

\1 es la syntax de la última captura en una expresión regular usando el () como dijiste. Dice lo que fue emparejado, reemplazarlo con eso.

Puedes usar continuamente los grupos () y sus respectivos \2 para continuar reemplazando lo que hiciste coincidir.