• Publicidad

Reemplazar solo un carácter entre comillas

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Reemplazar solo un carácter entre comillas

Notapor Skull118 » 2013-08-07 17:03 @752

Buenas tardes, maestros de Perl en español, tengo el siguiente inconveniente:

Tengo un CSV, que obviamente va separado por comas, pero a veces en la cadena (vista como texto), hay algo como esto

aquí va algo,aquí va algo más,"ESTO ES UNA CADENA, EN LA CUAL, NECESITO, ELIMINAR, TODAS, LAS COMAS QUE APARECEN, DENTRO DE LAS COMILLAS", aquí va algo más, y aquí algo más

Lo anterior es por poner un ejemplo.

He intentado varias combinaciones de expresiones regulares para reemplazar SOLO LAS COMAS que están dentro de las comillas, pero no logro reemplazarlas con un espacio o bien eliminarlas, para que la cadena termine así:

aquí va algo,aquí va algo más,"ESTO ES UNA CADENA EN LA CUAL NECESITO ELIMINAR TODAS LAS COMAS QUE APARECEN DENTRO DE LAS COMILLAS", aquí va algo más, y aquí algo más

De antemano, muchas gracias.
Skull118
Perlero nuevo
Perlero nuevo
 
Mensajes: 53
Registrado: 2013-03-21 13:38 @610

Publicidad

Re: Reemplazar solo un carácter entre comillas

Notapor Skull118 » 2013-08-07 17:34 @774

Logré desarrollar la expresión regular, la dejo aquí por si a alguien más le sirve.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. ([^\x22][^a-z][^a-Z][^0-9])?,([^a-z][^a-Z][^0-9][^\x22])?
  2.  
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4
Skull118
Perlero nuevo
Perlero nuevo
 
Mensajes: 53
Registrado: 2013-03-21 13:38 @610

Re: Reemplazar solo un carácter entre comillas

Notapor explorer » 2013-08-07 23:29 @020

Esta es mi versión:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use v5.10;
  3.  
  4. my $linea = q(aquí va algo,"OTRA",aquí va algo más,"ESTO ES UNA CADENA, EN LA CUAL, NECESITO, ELIMINAR, TODAS, LAS COMAS QUE APARECEN, DENTRO DE LAS COMILLAS", aquí va algo más, y aquí algo más);
  5.  
  6. 1 while                         # un bucle que no hace nada mientras se puede hacer alguna sustitución
  7.     $linea =~ s/
  8.                 (?:^|,)         # principio de línea o de campo
  9.                 "               # seguido por unas comillas dobles
  10.                [^"]*?          # seguidas por un número indeterminado de caracteres que no contienen unas comillas
  11.                 \K              # vale, pues si hemos encontrado eso, no nos interesa cambiarlo
  12.                 ,               # esto es lo único que cambiaremos: una coma
  13.                 (?=             # siempre y cuando esa coma esté seguida por
  14.                     .*?         # un número indeterminado de caracteres que no contienen comillas dobles
  15.                     "           # seguidos, inmediatamente por unas comillas dobles
  16.                )
  17.                //x;            # la coma encontrada es cambiada por nada (es eliminada)
  18.  
  19. say $linea;
  20. __END__
  21. aquí va algo,"OTRA",aquí va algo más,"ESTO ES UNA CADENA EN LA CUAL NECESITO ELIMINAR TODAS LAS COMAS QUE APARECEN DENTRO DE LAS COMILLAS", aquí va algo más, y aquí algo más
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
La línea 6 se puede compactar en:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. 1 while $linea =~ s/(?:^|,)"[^"]*?\K,(?=.*?")//;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Aunque... lo más cómodo sería usar Text::CSV, sacar el campo, filtrarlo con un simple s/,//g, y recrear el archivo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Reemplazar solo un carácter entre comillas

Notapor Skull118 » 2013-08-08 11:59 @541

Muchas gracia,s explorer, definitivamente el mejor en el tema. La expresión que realicé funciona, pero parcialmente, no es tan exacta como la tuya :shock: Solamente otra duda, maestro: ¿dónde puedo encontrar un tutorial para poder programar expresiones regulares, a tal nivel? Lo que he aprendido, lo he buscado y entendido a grandes rasgos. Si tuvieras una página donde pudiera aprenderlo, te lo agradecería mucho.

Todo mi respeto, y agradecimiento, un abrazo desde Guatemala.
Skull118
Perlero nuevo
Perlero nuevo
 
Mensajes: 53
Registrado: 2013-03-21 13:38 @610

Re: Reemplazar solo un carácter entre comillas

Notapor explorer » 2013-08-08 12:48 @575

Bueno, en Internet hay muchos recursos para aprender expresiones regulares, solo es cuestión de buscarlas, pero te cuento cómo aprendí yo: leyendo el libro "Mastering Regular Expressions", de O'Reilly. Bueno, el caso es que es un libro de alto nivel, casi matemático, pues enseña cómo funcionan las expresiones regulares desde dentro. Y las particularidades de sus implementaciones en cada lenguaje informático.

Perl sobresale en todos los aspectos, pues tiene el mejor soporte de expresiones regulares.

Tampoco tienes que ir muy lejos... en tu propio ordenador, en la documentación de Perl, hay varios documentos al respecto:
  • perldoc perlrequick - tutorial rápido de expresiones regulares (traduciéndose al español)
  • perldoc perlretut - tutorial de expresiones regulares
  • perldoc perlre - manual de expresiones regulares (traducido al español)
  • perldoc perlrebackslash - Secuencias de escape en expresiones regulares
  • perldoc perlrecharclass - Clases de caracteres en expresiones regulares
  • perldoc perlreref - Referencia rápida de expresiones regulares
  • perldoc perlreapi - Interfaz de complementos: expresiones regulares
  • perldoc perlreguts - Componentes del motor de expresiones regulares
Los dos últimos no te interesan, salvo que tengas un interés real en saber cómo funciona la implementación de exp. reg. dentro de perl. Los que sí te interesan son los tutoriales y manuales.

En la sección de Tutoriales de esta web, hay un par de ellos. En la Wikipedia, en la página de Expresiones regulares, también hay una introducción y más enlaces a más tutoriales. La versión inglesa de esa página tiene mucha más información y más enlaces.

Para resolver tu caso, solo he tenido que consultar perlre, pero claro, como todo manual, es muy pesado de leer.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Reemplazar solo un carácter entre comillas

Notapor explorer » 2013-08-08 13:28 @603

Hola, he encontrado una solución mejor.
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $linea =~ s/(?:^|,)"\K(.*?)(?=")/(my $x = $1) =~ tr{,}{}d; $x/ge;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
El funcionamiento es más óptimo, ya que no se ejecuta el bucle while().

El funcionamiento es, además, más claro.
  • se trata de una exp. reg. que se aplica de forma global (/g) a la variable $linea
  • el patrón intenta localizar unas comillas dobles, tanto al principio de la variable o justo después de una ','
  • si es así, obvia lo encontrado hasta el momento (\K) y sigue buscando concordancias
  • capturamos todo lo que encontremos ((.*?))
  • hasta justo antes de la siguiente comilla, que no es capturada ((?="))
  • el resultado es la captura en $1 de sólo lo que está entrecomillado doble
  • la parte de sustitución es un código ejecutable (/e) en Perl
  • el código, lo que hace es hacer una copia de $1 en $x, y realizar una transliteración (tr{}{})
  • la transliteración busca comas, y las borra (/d)
  • y termina devolviendo $x con las comas ya filtradas, que se incorpora como cambio a $linea
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 20 invitados