2012-03-27 9 views
80

Tengo problemas para traducir esto en Ruby.Ruby reemplazar cadena con patrón de expresión regex capturada

Aquí es un fragmento de código JavaScript que hace exactamente lo que quiero hacer:

function get_code(str){ 
    return str.replace(/^(Z_.*): .*/,"$1")​​​​​​​​​​​​​​​​​​​​​​​​​​​; 
} 

He tratado gsub, sub y replace pero ninguno parece hacer lo que estoy esperando.

Éstos son ejemplos de cosas que he intentado:

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/) { |capture| capture } 
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "$1") 
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "#{$1}") 
"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\1") 
"Z_sdsd: sdsd".gsub(/(.).*/) { |capture| capture } 
+0

usted debe mostrar el código real por lo que has intentó. – Amber

+0

@Amber pongo la muestra que he probado. –

Respuesta

138

Trate '\1' para la sustitución (comillas simples son importantes, de lo contrario se necesita para escapar de la \):

"foo".gsub(/(o+)/, '\1\1\1') 
#=> "foooooo" 

Pero como parece que solo le interesa el grupo de captura, tenga en cuenta que puede indexar una cadena con una expresión regular:

"foo"[/oo/] 
#=> "oo" 
"Z_123: foobar"[/^Z_.*(?=:)/] 
#=> "Z_123" 
+56

Tenga en cuenta que esto solo funciona si la cadena de reemplazo está dentro de ** comillas simples **. Perdí 5 minutos pensando en eso. –

+7

@MarkThomas - muchas veces probamos la respuesta superior/aceptada primero sin leer la totalidad de las respuestas. Ese parece ser, en general, el medio más eficiente para solucionar un problema. ¡Dale un descanso a Vicky! :) –

+0

@VickyChijwani Buen comentario, pero también tenga en cuenta que al usar Ruby en línea (en la línea de comandos con '-e'), es más probable que vea ** comillas dobles **:' printf "Punkinhead el nombre" | ruby -ne 'pone gsub /.*(el nombre) /, "Jonathans \\ 1"' 'porque la expresión proporcionada a' -e' se envuelve generalmente en comillas simples. –

1
def get_code(str) 
    str.sub(/^(Z_.*): .*/, '\1') 
end 
get_code('Z_foo: bar!') # => "Z_foo" 
29

\1 en comillas dobles debe escaparse. Por lo que desea, ya sea

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, "\\1") 

o

"Z_sdsd: sdsd".gsub(/^(Z_.*): .*/, '\1') 

ver the docs on gsub donde dice "Si se trata de una cadena entre comillas dobles, ambas copias de referencias debe ir precedida de una barra inversa adicional."

Dicho esto, si lo que desea el resultado del partido que puede hacer:

"Z_sdsd: sdsd".scan(/^Z_.*(?=:)/) 

o

"Z_sdsd: sdsd"[/^Z_.*(?=:)/] 

Tenga en cuenta que la (?=:) es un grupo sin fines de capturar de manera que el : no aparece en tu partida.

8
"foobar".gsub(/(o+)/){|s|s+'ball'} 
#=> "fooballbar" 
+2

no sabía que podía hacer eso. ¡Bonito! – vreen

1

Si es necesario utilizar una expresión regular para filtrar algunos resultados, y luego usar sólo el grupo de captura, puede hacer lo siguiente:

str = "Leesburg, Virginia 20176" 
state_regex = Regexp.new(/,\s*([A-Za-z]{2,})\s*\d{5,}/) 
# looks for the comma, possible whitespace, captures alpha, 
# looks for possible whitespace, looks for zip 

> str[state_regex] 
=> ", Virginia 20176" 

> str[state_regex, 1] # use the capture group 
=> "Virginia" 
Cuestiones relacionadas