¿Cómo usar ruby gsub Regexp con muchas coincidencias?
gsub ruby (2)
Asumiendo que s
es una cadena, esto funcionará:
puts s.gsub(/([^,])"([^,])/, "//1/"/"//2")
Tengo el contenido del archivo csv con comillas dobles dentro del texto citado
test,first,line,"you are a "kind" man",thanks
again,second,li,"my "boss" is you",good
Necesito reemplazar cada comilla doble que no esté precedida o seguida por una coma por ""
test,first,line,"you are a ""kind"" man",thanks
again,second,li,"my ""boss"" is you",good
por lo que "se sustituye por" "
Lo intenté
x.gsub(/([^,])"([^,])/, "#{$1}/"/"#{$2}")
pero no funcionó
Su expresión regular debe ser un poco más en negrita, en caso de que las comillas aparezcan al comienzo del primer valor, o al final del último valor:
csv = <<ENDCSV
test,first,line,"you are a "kind" man",thanks
again,second,li,"my "boss" is you",good
more,""Someone" said that you''re "cute"",yay
"watch out for this",and,also,"this test case"
ENDCSV
puts csv.gsub(/(?<!^|,)"(?!,|$)/,''""'')
#=> test,first,line,"you are a ""kind"" man",thanks
#=> again,second,li,"my ""boss"" is you",good
#=> more,"""Someone"" said that you''re ""cute""",yay
#=> "watch out for this",and,also,"this test case"
La expresión regular anterior utiliza aserciones de lookbeth negativo y lookahead negativo (anclas) disponibles en Ruby 1.9.
-
(?<!^|,)
: Inmediatamente antes de este punto no debe haber un inicio de línea (^
) ni una coma -
"
- encontrar una cita doble -
(?!,|$)
: Inmediatamente después de este punto no debe haber una coma ni un final de línea ($
)
Como beneficio adicional, ya que en realidad no capturó los caracteres en ninguno de los lados, no debe preocuparse por usar /1
correctamente en la cadena de reemplazo.
Para obtener más información, consulte la sección "Anclas" en la documentación oficial de expresiones regulares de Ruby .
Sin embargo, en el caso de que necesite reemplazar coincidencias en su salida, puede usar cualquiera de los siguientes:
"hello".gsub /([aeiou])/, ''</1>'' #=> "h<e>ll<o>"
"hello".gsub /([aeiou])/, "<//1>" #=> "h<e>ll<o>"
"hello".gsub(/([aeiou])/){ |m| "<#{$1}>" } #=> "h<e>ll<o>"
No puedes usar la interpolación de cadenas en la cadena de reemplazo, como hiciste:
"hello".gsub /([aeiou])/, "<#{$1}>"
#=> "h<previousmatch>ll<previousmatch>"
... porque esa interpolación de cadenas ocurre una vez, antes de que se haya ejecutado el gsub
. El uso de la forma de bloque de gsub
re-invoca el bloque para cada coincidencia, momento en el cual el $1
global se ha completado correctamente y está disponible para su uso.
Edición : Para Ruby 1.8 (¿por qué demonios estás usando eso?) Puedes usar:
puts csv.gsub(/([^,/n/r])"([^,/n/r])/,''/1""/2'')