Discussion:
Como lo hago... duda de algoritmo..
(demasiado antiguo para responder)
Horacio Castellini
2004-06-08 20:16:33 UTC
Permalink
Holas...

Si alguien me tira una linea de como eliminar partes espureas de
una lista de cadenas... por ejemplo... en

From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:MaximilianoMuller<maximuller_al_ciudad.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:AlejandroGomezFernandez<agomez_al_micropack.com.ar>
From:FranchiSantiago<SFRANCHI_al_pecom.com>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:EduardoJorgeMartinezVelez<ejmv_al_accesofree.com>
From:AlejandroGomezFernandez<agomez_al_micropack.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:mariano<montever_al_netcoop.com.ar>
From:mariano<montever_al_netcoop.com.ar>

desearía eliminar From:" ó From: y la dirección de correo contenida en
<..> incluido el "<, <,> según sea el caso para que quede solo los
nombres... limpios... de la siguiente forma...

EduardoJorgeMartinezVelez
AlejandroGomezFernandez
SebastiánCriado
mariano
mariano

Se entiende no?...

Saludos y Gracias Horacio...
Lokutus
2004-06-08 23:53:24 UTC
Permalink
El tal Horacio Castellini en la fecha Martes 08 Junio 2004 22:16 escribio
Post by Horacio Castellini
Holas...
Si alguien me tira una linea de como eliminar partes espureas de
una lista de cadenas... por ejemplo... en
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
Con strtok()

Primero cortas usando el caracter ":" como separador

Y despues usando el caracter "<"

Te quedaría la cadena con el nombre del que sóllo tienes
que quitar las comillas.


Voy a hacer una funcioncita, y aprovecho para hacer en forma de
comentario, su contrato, ahora que está de "moda" el tema de la
programación por contratos, (bueno, eso sería más en la fase de
análisis, pero para ir practicando).


... Cortar monitor por aqui ..................................

#include <stdio.h>
#include <string.h>

/* Prototipos */
char *megaTrimDeLosBosques(char *sIn, char cCar)


/* ********************************************************
*
* Nombre: extraeNombre(char *sDireccion,
* char *sNombre, int iLong);
*
* Responsabilidades: Dada una cadena de texto con el
* formato From:"nombre"<***@dominio>, extraer
* de esa cadena el nombre delimitado por comillas.
*
* Tipo: Código.
*
* Referencias Cruzadas: (Casos de uso, pero aqui no afectan).
*
* Notas: Esta funcion no ha sido probada ni compilada.
*
* Excepciones: ninguna.
*
* Entrada:
*
* sDireccion: contiene una cadena ASCIIZ con la
* dirección de correo de la que hay
* que extraer el nombre.
*
* iLong: es el tamaño de buffer sNombre.
*
* Salida:
*
* El valor de retorno será 0 si la función funcionó
* correctamente o -1 si hubo algún error.
*
* sNombre: es un puntero a un buffer lo suficientemente
* grande como para contener el nombre de la dirección
* de correo. Su tamaño es especificado por el valor de
* iLong. Si el buffer es demasiado pequenio, el contenido
* quedara truncado.
*
* Precondiciones:
*
* La función no tomará suposiciones acerca del estado de
* los parámetros antes de su ejecución. Tanto el punteros a
* sDireccion como a sNombre puede estar a NULL. La cadena
* sDireccion puede estar vacia.
*
* Postcondiciones:
*
* El contenido de sDireccion quedara destruido tanto si
* la funcion se ejecuto correctamente como si no, por lo tanto
* si se desea conservar su valor, se aconseja hacer una copia
* antes de usar.
*
* **************************************************************/
int extraeNombre(char *sDireccion, char *sNombre, int iLong)
{

char *sAuxil; /* Cadena auxiliar para resultado de strtok */
int iRetorno; /* Valor de retorno de la funcion. */

iRetorno = 0;

if ((sDireccion == (char *) NULL) || (sNombre == (char *) NULL)) {
iRetorno = -1;
} else {

/* Quitamos del from: */
sAuxil = strtok(sNombre, ":");
if (sAuxil == (char *) NULL) {
iRetorno = -1;
} else {

/* Aqui nos quedaría "nombre"<***@dominio> */

sAuxil = strtok((char *) NULL, "<");
if (sAuxil == (char *) NULL) {
iRetorno = -1;
} else {

/* Aqui tenemos presuntamente en sAuxil el nombre
que puede estar entre comillas. */

/* Eliminamos espacios sobrantes */
sAuxil = megaTrimDeLosBosques(sAuxil, ' ');

/* Eliminamos las comillas */
sAuxil = megaTrimDeLosBosques(sAuxil, '\"');

strncpy(sNombre, sAuxil, iLong);

/* Por que strncpy no garantiza un cero final,
cuando el tamanio de sAuxil es mayor que iLong */
sNombre[iLong - 1] = (char) NULL;

} /* if */
} /* if */
} /* if */

return iRetorno;

} /* dejaNombre */


/* Elimina el caracter especificado tanto a derecha como a izquierda,
* Esta función no ha sido probada, y la he rescatado de cuando salio
* el tema del trim en el foro de C++. Para ver las alternativas de
* los demas contertulios, buscar "megatrimdelosbosques" en google
* groups y pinchar en "ver la conversacion (30 mensajes)"
*/
char *megaTrimDeLosBosques(char *sIn, char cCar)
{

// -1 por que se posicionaría en el 0 final.
char *sPos = sIn + strlen(sIn) - 1;
char *sDes = sIn;

while((sPos == cCar) && (sPos > sIn)) sPos--;
*(sPos + 1) = (char) NULL;
sPos = sIn;
while(*sPos == cCar) sPos++;
while(*sPos != (char) NULL) {
*sDes = *sPos;
sDes++;
sPos++;
} // while
sDes = (char) NULL;
return(sDes);

} /* megaTrimDeLosBosques */

....................... EOF ...................................

Observa que si quitamos los comentarios, asumimos que los parámetros
de entrada van a ser correctos, y que no van a quedar espacios
residuales y que siempre van a existir comillas, puedes reducirlo todo
a una mierdecilla de funcion.
--
Lokutus, asimilando la red.
JGauss
2004-06-09 00:21:56 UTC
Permalink
Horacio Castellini wrote:

#include <string.h> // <== MIRATE LAS FUNCIONES DE ESTE FICHERO

void DimeElNombre(char *cadenacompleta, char *nombre)
{
char *ptr;

if (*(cadenacompleta+5) == '"') { //es un From:"nombre"<email>
strcpy(nombre,cadenacompleta+6);
ptr = strchr(nombre,'"');
} else { //es un From:nombre<email>
strcpy(nombre,cadenacompleta+5);
ptr = strchr(nombre,'<');
}
*ptr = 0;
}

ó

void DimeElNombre(char *cadenacompleta, char *nombre)
{
char *ptr;

strcpy(nombre,cadenacompleta+5);
ptr = strchr(nombre,'<');
*ptr = 0;
}

Y le quitas las comillas con otra función al nombre
que las tuviese.

//---//

No lo he probado, pero básicamente es eso; teniendo
en cuenta que sólo funciona para esos ejemplos, puesto que
si es lo que creo que es, una cabecera "from" de un correo
o de una noticia nntp, el algoritmo, para ser efectivo,
debería ser algo más complejo y completo; tú mismo.

Salud!
Post by Horacio Castellini
desearía eliminar From:" ó From: y la dirección de correo contenida en
<..> incluido el "<, <,> según sea el caso para que quede solo los
nombres... limpios... de la siguiente forma...
--
JGauss

@ CYGWIN_NT-5.1 - Kernel 1.5.9(0.112/4/2) - KNode: 0.7.2 @

www.pce.es | www.izquierda-unida.es
Horacio Castellini
2004-06-09 21:53:12 UTC
Permalink
On Wed, 9 Jun 2004, JGauss wrote:

Gracias Gauss,, me diste una buena idéa... nos vemos... ;)
Post by JGauss
#include <string.h> // <== MIRATE LAS FUNCIONES DE ESTE FICHERO
void DimeElNombre(char *cadenacompleta, char *nombre)
{
char *ptr;
if (*(cadenacompleta+5) == '"') { //es un From:"nombre"<email>
strcpy(nombre,cadenacompleta+6);
ptr = strchr(nombre,'"');
} else { //es un From:nombre<email>
strcpy(nombre,cadenacompleta+5);
ptr = strchr(nombre,'<');
}
*ptr = 0;
}
ó
void DimeElNombre(char *cadenacompleta, char *nombre)
{
char *ptr;
strcpy(nombre,cadenacompleta+5);
ptr = strchr(nombre,'<');
*ptr = 0;
}
Y le quitas las comillas con otra función al nombre
que las tuviese.
//---//
J.A. Gutierrez
2004-06-09 10:09:18 UTC
Permalink
Horacio Castellini <***@fceia.unr.edu.ar> wrote:

: desearía eliminar From:" ó From: y la dirección de correo contenida en
: <..> incluido el "<, <,> según sea el caso para que quede solo los
: nombres... limpios... de la siguiente forma...

la forma mas correcta seria recurrir a funciones de libreria
para tratar con expresiones regulares.
Si no, si quieres la misma robustez, tendras que meter bastante
codigo para tener en cuenta todos los casos.

Luego, si, como supongo, estas leyendo de mensajes de correo,
ten en cuenta que muchas veces los nombres reales vienen como
quoted-printable.

Sugerencia: pillate las fuentes de un agente de correo (p.e.
mutt) y mira a ver como lo hace.

Alternativa: hazlo con un filtro en sed o perl o egrep.
--
finger ***@shiva.cps.unizar.es for PGP /
.mailcap tip of the day: / La vida es una carcel
application/ms-tnef; cat '%s' > /dev/null / con las puertas abiertas
text/x-vcard; cat '%s' > /dev/null / (A. Calamaro)
BitterB
2004-06-10 02:14:31 UTC
Permalink
Post by Horacio Castellini
Holas...
Hola, que tal?
Post by Horacio Castellini
Si alguien me tira una linea de como eliminar partes espureas de
una lista de cadenas... por ejemplo... en
From:EduardoJorgeMartinezVelez<ejmv_al_accesofree.com>
From:AlejandroGomezFernandez<agomez_al_micropack.com.ar>
From:"SebastiánCriado"<scriado_al_ciudad.com.ar>
From:mariano<montever_al_netcoop.com.ar>
From:mariano<montever_al_netcoop.com.ar>
desearía eliminar From:" ó From: y la dirección de correo contenida en
<..> incluido el "<, <,> según sea el caso para que quede solo los
nombres... limpios... de la siguiente forma...
EduardoJorgeMartinezVelez
AlejandroGomezFernandez
SebastiánCriado
mariano
mariano
Se entiende no?...
Ok, pues asi a bote pronto si estas usando linux seguramente tengas por ahi
a flex, que es un generador de analizadores lexicos y va muy bien para lo
que tu quieres hacer. En caso de que uses algun otro sistema operativo que
circula por ahi tambien existen versiones de lex (creo que aqui se llama
pclex) que seguro puedes buscar y descargar mediante google.
Como pides algo de codigo aqui te dejo lo primero que se me ha ocurrido
hacer con flex:

%{
#include <string.h>
char *cadena = NULL;
%}
NOMBRE [A-Za-z0-9]

%%

"\""{NOMBRE}+"\"" {
cadena = strtok(yytext,"\"");
printf("%s\n", cadena);
}
":"{NOMBRE}+"<" {
cadena = strtok(yytext,":<");
printf("%s\n", cadena);
}
.

%%

main () {
yylex();
}

El uso de flex es sencillo (dependiendo de lo que quieras hacer con el
claro), copia el anterior codigo en un archivo y pasaselo de esta forma:
flex nombre_archivo Esto te genera un archivo en c con el analizador lexico
que se llama lex.yy.c, ahora solo tienes que compilar este archivo, en
linux algo asi como: gcc lex.yy.c -lfl Despues de eso ya tendras el
ejecutable que leera las cadenas de texto de la entrada estandar y mostrara
el resultado, lo he probado con las que incluyes en el post y funciona.
Ahora habria que hacer que leyera las direcciones de correo de un archivo y
retocarlo un poquito, pero como has pedido solo una linea de codigo..... ;)
Si no quieres utilizar lex echale un vistazo a la funcion strtok y seguro
que con un poco de imaginacion se te ocurre como sacarle partido.
Post by Horacio Castellini
Saludos y Gracias Horacio...
Saludos a ti tambien.
--
Vamos a crear una civilizacion de la mente en el ciberespacio. Que sea mas
humana y hermosa que el mundo que vuestros gobiernos han creado hasta
ahora.
Loading...