• Publicidad

Incorporar texto estructurado a una BD

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

Incorporar texto estructurado a una BD

Notapor preiddy » 2006-03-29 06:17 @303

Hola, tengo un archivo con la siguiente características:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1. FN ISI Export Format
2. VR 1.0
3. PT J
4. AU Porras, MD
        Otro, AR
        Y OTRO, OFG
5. TI Three Venezuelan literary journals of the 1960s and the problem of
   culture
6. SO REVISTA IBEROAMERICANA
7. LA Spanish
8. DT Article
9. C1 Univ Simon Bolivar, Caracas 1080, Venezuela.
        Otra Univ Simon Bolivar, Caracas 1080, Venezuela.
        Y OTRA Univ Simon Bolivar, Caracas 1080, Venezuela.
10. RP Porras, MD, Univ Simon Bolivar, Caracas 1080, Venezuela.
11. CR 1958, SARDIO, V1, P1
         1959, SARDIO, V5, P277
         1961, RAYADO TECHO BALLENA
         1961, SARDO, V8, P136
         1963, RAYADO TECHO, V2
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Los números de lineas no vienen, los puse para explicar mejor mi problema.

Las líneas 1 y 2 son un encabezado del archivo descargado, solo aparecen una vez, no son relevantes al menos que se quiera verificar si es o no un registro con la estructura que se espera, para ello hice esto:

print "No es un registro ISI" if ($_ =~ m/[1-9]/);

Luego leo cada línea y la meto en un array. El problema surge cuando la línea 4-9-11 tiene más de un elemento (autores) con su respectivo salto de línea.

Luego la línea 5 suele estar cortada y el texto continúa en una nueva línea, lo idóneo es que esto todo en una misma línea.

Creé un bucle con if donde extraigo el campo a etiquetar con una expresión regular, quedando así:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. foreach $campo (@registro)
  2.  
  3. {
  4.  
  5.     if ( $campo =~ /^AU:/ )
  6.  
  7.     {
  8.  
  9.         print "\"$campo\",";
  10.  
  11.     }
  12.  
  13.     elsif ( $campo =~ /^DT:/ )
  14.  
  15.     {
  16.  
  17.         print "\"$campo\",";
  18.  
  19.     }
  20.  
  21.     elsif ( $campo =~ /^PY:/ )
  22.  
  23.     {
  24.  
  25.         print "\"$campo\",";
  26.  
  27.     }
  28.  
  29.     elsif ( $campo =~ /^LA:/ )
  30.  
  31.     {
  32.  
  33.         print "\"$campo\",";
  34.  
  35.     }
  36.  
  37.     elsif ( $campo =~ /^TI:/ )
  38.  
  39.     {
  40.  
  41.         print "\"$campo\",";
  42.  
  43.     }
  44.  
  45.     elsif ( $campo =~ /^SO:/ )
  46.  
  47.     {
  48.  
  49.         print "\"$campo\",";
  50.  
  51.     }
  52.  
  53. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

El problema de esto es que si un elemento no existe debería imprimir un mensaje de campo vacío o NULL. Además de no tomar el resto de líneas que mencione antes (4, 9 y 11).

Si me pueden ayudar, de antemano, Gracias.
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Publicidad

Re: Incorporar texto estructurado a una BD

Notapor explorer » 2006-03-29 13:27 @602

Yo necesitaría un par de ejemplos...
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

Notapor kidd » 2006-03-29 18:46 @823

Hola.

Antes que nada, bienvenido al foro.

Tampoco yo termino por comprender exactamente lo que quieres hacer.

Puedes poner un ejemplo del texto original y otro en donde venga ya el resultado que quieres, de esa manera podemos entender un poco lo que quieres quitar o agregar.

También te recomiendo que uses la marca [code] para que podamos diferenciar los pedazos de código.

Saludos
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Incorporar texto estructurado a una BD

Notapor preiddy » 2006-03-30 04:31 @229

Gracias por la bienvenida y las respuestas, :D

Comienzo de nuevo: tengo un archivo de texto con la siguiente estructura:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
FN ISI Export Format
VR 1.0
PT J
AU Porras, MD
Potras, AD
Rovero, GK
TI Three Venezuelan literary journals of the 1960s and the problem of
   culture
SO REVISTA IBEROAMERICANA
LA Spanish
DT Article
C1 Univ Simon Bolivar, Caracas 1080, Venezuela.
RP Porras, MD, Univ Simon Bolivar, Caracas 1080, Venezuela.
CR 1958, SARDIO, V1, P1
   1959, SARDIO, V5, P277
   1961, RAYADO TECHO BALLENA
   1961, SARDO, V8, P136
   1963, RAYADO TECHO, V2
   BELLO AA, 1959, TABLA REDONDA, V4, P4
NR 21
TC 0
PU INST INT LIT IBEROAMERICANA
PI PITTSBURGH
PA UNIV PITTSBURGH ATTN: ERIKA BRAGA 1312 CATHEDRAL OF LEARNING,
   PITTSBURGH, PA 15260 USA
SN 0034-9631
J9 REV IBEROAMERICANA
JI Rev. Imberoam.
PD JUL-DEC
PY 2004
VL 70
IS 208-9
BP 875
EP 890
PG 16
SC Literature, Romance
GA 862QM
UT ISI:000224505900015
ER

PT J
AU Rovero, GK
Porras, MD
TI The Latin-American novelist between the Gutemberg galaxy and the
   electronic galaxy - Writers, readers and the "technoperception" of the
   world
SO HISPAMERICA-REVISTA DE LITERATURA
LA Spanish
DT Article
C1 Univ Simon Bolivar, Caracas 1080, Venezuela.
   Cent Univ Venezuela, Escuela Letras, Caracas, Venezuela.
RP Rovero, GK, Univ Simon Bolivar, Caracas 1080, Venezuela.
CR 1991, METAMORFOSIS CULTURA, P174
   BARBERO JM, 1993, REV CRITICA CULTURAL, V7, P20
   BARBERO JM, 1998, MEDIOS MEDIACIONES, P67
   ISER W, 1997, TEORIAS FICCION LIT, P57
   OLAECHEA J, 1986, LIBRO ECOSISTEMA COM, P137
NR 14
TC 0
PU HISPAMERICA
PI GAITHERSBURG
PA SAUL SOSNOWSKI 5 PUEBLO COURT, GAITHERSBURG, MD 20878 USA
SN 0363-0471
J9 HISPAMERICA-REV LIT
JI Hispamerica-Rev. Lit.
PD AUG
PY 2004
VL 33
IS 98
BP 37
EP 47
PG 11
SC Literature, Romance
GA 906XD
UT ISI:000227677200003
ER
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Las dos primera letras en mayúsculas en cada línea determinan el nombre del campo. Cada registro comienza con PT y termina con ER.
Los campos AU, TI, C1, RP y CR contienen datos en más de una línea, pero el campo TI (título) debería ir todo en una sola línea.

Lo que necesito hacer es meter cada campo en una base de datos, y que cuando en el archivo no exista un campo en la base de datos se inserte NULL.

Lo primero que se me ocurrió fue meterlo todo en un array, separando cada registro con una barra (|).
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. $fichero = 'idb1.txt';
  2. open( INFO, $fichero );
  3. @info = <INFO>;
  4. while (@info) {
  5.     @reg = split(/ER-\|/);
  6.     print @reg;
  7. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Luego recorrer el array y con if() ver si existe cada campo e insertarlo en la BD, con el código que puse antes:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. foreach $campo (@registro) {
  2.     if ( $campo =~ /^AU/ ) {
  3.         print $campo;
  4.     }
  5.     elsif ( $campo =~ /^DT/ ) {
  6.         print $campo;
  7.     }
  8.     elsif ( $campo =~ /^PY/ ) {
  9.         print $campo;
  10.     }
  11.     elsif ( $campo =~ /^LA/ ) {
  12.         print $campo;
  13.     }
  14.     elsif ( $campo =~ /^TI/ ) {
  15.         print $campo;
  16.     }
  17.     elsif ( $campo =~ /^SO/ ) {
  18.         print $campo;
  19.     }
  20. }
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Bueno, aunque más que un print() debería construir la consulta para insertar en la BD, eso no lo sé hacer.

Los problemas de todo lo anterior es que si un campo tiene más de una línea no recupero esas líneas, y de recuperarlas cada una debería estar separada por punto y coma; si un campo no aparece debería poner NULL porque sino se mueven los valores y no se insertan en el campo que le corresponde.

La verdad es que llevo ya un tiempo con esto y no veo la luz al final del túnel, ¡ja,ja,ja!

Al final debería quedar algo como esto:

INSERT INTO TABLA (PT,AU,TI,SO,LA,DT,DE,etc...) VALUES ($PT,$AU,etc..)

pero si por ejemplo $AU no tiene nada, que inserte la palabra NULL o vacío.

Espero haberme explicado un poco mejor, no he estudiado programación y me cuesta explicarme, gracias por las respuestas y paciencia a este novato.

Gracias. :lol:
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: Incorporar texto estructurado a una BD

Notapor explorer » 2006-03-30 04:53 @245

Respuesta rápida.

Puedes indicar en la definición de la tabla de la base de datos que, cuando un campo no reciba ningún valor, su valor por defecto sea NULL.

Creo recordar que era algo así como

NOMBRE char(255) default NULL,
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

Notapor preiddy » 2006-03-30 06:04 @294

Ok, gracias por la respuesta.

Pero ahora me surge otra duda: si en el sql digo o declaro campo "x" y luego no se le pasa ningún valor, ¿no dará error?
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Notapor macgregor » 2006-03-30 06:48 @325

Hola.

Una posible solución sería crear una variable para cada campo. La puedes declarar como $variable="";, de manera que cuando insertes en la DB si no se ha modificado el valor, se insertará NULL.

Lo delicado es analizar el fichero para asignar cada cosa a una de tus variables.

No sé si siempre aparecen todos los campos, si además lo hacen en el mismo orden, si cuando es nulo aparecen solo las dos primeras letras que has comentado...

Respecto a tu última pregunta, te dará error dependiendo de cómo hagas la consulta.

Si haces insert into tabla(id_tabla, campo1,campo3,campo4) values (123,$variable1,$variable3,$variable4) no te dará error a no ser que tu campo 2 no admita nulos, ya que te insertará NULL en este campo.

Si haces insert into tabla(id_tabla, campo1,campo2,campo3,campo4) values (123,$variable1,$variable3,$variable4) está claro que se quejará diciendo que le falta un valor.
MACGREGOR [TM]
Avatar de Usuario
macgregor
Perlero nuevo
Perlero nuevo
 
Mensajes: 80
Registrado: 2004-12-09 07:32 @355
Ubicación: españa

Notapor preiddy » 2006-03-30 08:52 @411

Efectivamente, no siempre aparecen todos los campos.

Eso sí: cuando aparecen mantienen el mismo orden, uno de bajo del otro.
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Re: Incorporar texto estructurado a una BD

Notapor explorer » 2006-03-30 11:09 @506

Bueno, he encontrado una solución.
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
* Leemos toda la base de datos en una única variable escalar
* Por cada registro dentro de esa variable...
*  Por cada campo posible...
*    Sacamos el valor de ese campo, que esta entre él y el siguiente
*  Construimos la consulta con todos los campos encontrados
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2.  
  3. use warnings;
  4. use strict;
  5.  
  6. # Campos de cada registro
  7. # Nos servirán para buscarles dentro del registro
  8. my @campos = qw(
  9.     AU TI SO LA DT C1 RP CR NR TC
  10.     PU PI PA SN J9 JI PD PY VL IS
  11.     BP EP PG SC GA UT ER
  12. );
  13.  
  14. # Nombres de los campos de registro en nuestra base de datos
  15. # Nos servirán para meter los valores en los campos de la base de datos
  16. my %campos = (
  17.     AU => 'Autor',       TI => 'Titulo',       SO => 'Organizacion',
  18.     LA => 'Idioma',      DT => 'Tipo',         C1 => 'Copyright',
  19.     RP => 'Propietario', CR => 'Registro',     NR => 'Referencia',
  20.     TC => 'Tomos',       PU => 'Universidad',  PI => 'Ciudad',
  21.     PA => 'Contacto',    SN => 'Serie',        J9 => 'Acronimo',
  22.     JI => 'Acronimo2',   PD => 'Fecha',        PY => 'Año',
  23.     VL => 'Volumen',     IS => 'Tamaño',       BP => 'Indice',
  24.     EP => 'Subindice',   PG => 'Subsubindice', SC => 'Categoria',
  25.     GA => 'IDCategoria', UT => 'ISBN',
  26. );
  27.  
  28. # Almacén de valores por cada registro
  29. # Aquí guardamos los valores que vamos encontrando en el registro
  30. my %registro;
  31.  
  32. # Leemos base de datos en texto
  33. my $base = do { local $/; open(BASE,"<kk.txt"); <BASE> };
  34.  
  35. # Recorremos toda la base por cada registro
  36. while ( $base =~ /(^PT.+?^ER *?$)/smg ) {
  37.     my $registro = $1;
  38.     my %registro = ();
  39.  
  40.     # Hacemos un bucle por todos los campos posibles
  41.     for(my $i=0; $i<@campos-1;$i++) {
  42.  
  43.         # Nombre del campo a buscar
  44.         my $campo_actual    = $campos[$i];
  45.  
  46.         # Buscamos el campo_siguiente que sí exista dentro del registro
  47.         # Esto es necesario porque no sabemos qué campos pueden faltar
  48.         my $campo_siguiente;
  49.         for (my $j=$i+1; $j<@campos; $j++) {
  50.             $campo_siguiente = $campos[$j];
  51.             last if $registro =~ /^$campo_siguiente /sm;
  52.         }
  53.  
  54.         # Buscamos el contenido del campo.
  55.         # Aquí es donde extraemos el valor del campo, que está entre él y el campo siguiente
  56.         my ($valor) = $registro =~ /^$campo_actual (.+?)^$campo_siguiente */ms;
  57.  
  58.         # Caso de que no exista... no hacemos nada...
  59.         unless ( defined $valor ) {
  60.             #print "$campo_actual:NULL (no existe)\n";
  61.             next;
  62.         }
  63.  
  64.         # Quitamos el retorno de carro y ajustamos el título a una sola línea
  65.         chomp $valor;
  66.         if ( $campo_actual eq 'TI' ) {
  67.             $valor =~ s/\n/ /g;
  68.             $valor =~ s/ +/ /g;
  69.         }
  70.  
  71.         # El campo está vacío, no hacemos nada
  72.         if ( $valor eq '' ) {
  73.             #print "$campo_actual:NULL (vacio)\n";
  74.             next;
  75.         }
  76.  
  77.         # Si tenemos algo, lo guardamos para luego
  78.         #print "$campo_actual:$valor\n";
  79.         $registro{$campo_actual} = $valor;
  80.     }
  81.  
  82.     # Después de analizar el registro, confeccionamos la consulta para la base de datos
  83.     my $query = 'INSERT tabla SET ';
  84.  
  85.     # Recorremos los campos sacados del registro
  86.     foreach my $campo ( keys %registro ) {
  87.         # Añadimos a la consulta. El nombre del campo lo sacamos de %campos definido arriba
  88.         $query .= qq( $campos{$campo} = "$registro{$campo}",);
  89.     }
  90.  
  91.     # Quitamos la última coma y la sustituimos por ';'
  92.     substr($query,-1,1) = ';';
  93.  
  94.     # Ejecutamos la consulta en la base de datos
  95.     print "$query\n", 'X'x40, "\n";
  96. }
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

La salida que me sale es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using sql Syntax Highlighting
  1. INSERT tabla SET  Categoria = "Literature, Romance", Idioma = "Spanish", Autor = "Porras, MD
  2. Potras, AD
  3. Rovero, GK", Tamaño = "208-9", Indice = "875", Universidad = "INST INT LIT IBEROAMERICANA", ISBN = "ISI:000224505900015", Subsubindice = "16", Registro = "1958, SARDIO, V1, P1
  4. 1959, SARDIO, V5, P277
  5. 1961, RAYADO TECHO BALLENA
  6. 1961, SARDO, V8, P136
  7. 1963, RAYADO TECHO, V2
  8. BELLO AA, 1959, TABLA REDONDA, V4, P4", Volumen = "70", Copyright = "Univ Simon Bolivar, Caracas 1080, Venezuela.", Acronimo = "REV IBEROAMERICANA", Contacto = "UNIV PITTSBURGH ATTN: ERIKA BRAGA 1312 CATHEDRAL OF LEARNING,
  9. PITTSBURGH, PA 15260 USA", Titulo = "Three Venezuelan literary journals of the 1960s and the problem of culture", Fecha = "JUL-DEC", Propietario = "Porras, MD, Univ Simon Bolivar, Caracas 1080, Venezuela.", Referencia = "21", Subindice = "890", Tipo = "Article", Acronimo2 = "Rev. Imberoam.", Año = "2004", Tomos = "0", Serie = "0034-9631", IDCategoria = "862QM", Organizacion = "REVISTA IBEROAMERICANA", Ciudad = "PITTSBURGH";
  10. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  11. INSERT tabla SET  Categoria = "Literature, Romance", Idioma = "Spanish", Autor = "Rovero, GK
  12. Porras, MD", Tamaño = "98", Indice = "37", Universidad = "HISPAMERICA", ISBN = "ISI:000227677200003", Subsubindice = "11", Registro = "1991, METAMORFOSIS CULTURA, P174
  13. BARBERO JM, 1993, REV CRITICA CULTURAL, V7, P20
  14. BARBERO JM, 1998, MEDIOS MEDIACIONES, P67
  15. ISER W, 1997, TEORIAS FICCION LIT, P57
  16. OLAECHEA J, 1986, LIBRO ECOSISTEMA COM, P137", Volumen = "33", Copyright = "Univ Simon Bolivar, Caracas 1080, Venezuela.
  17. Cent Univ Venezuela, Escuela Letras, Caracas, Venezuela.", Acronimo = "HISPAMERICA-REV LIT", Contacto = "SAUL SOSNOWSKI 5 PUEBLO COURT, GAITHERSBURG, MD 20878 USA", Titulo = "The Latin-American novelist between the Gutemberg galaxy and the electronic galaxy - Writers, readers and the "technoperception" of the world", Fecha = "AUG", Referencia = "14", Propietario = "Rovero, GK, Univ Simon Bolivar, Caracas 1080, Venezuela.", Subindice = "47", Tipo = "Article", Acronimo2 = "Hispamerica-Rev. Lit.", Año = "2004", Serie = "0363-0471", Tomos = "0", IDCategoria = "906XD", Organizacion = "HISPAMERICA-REVISTA DE LITERATURA", Ciudad = "GAITHERSBURG";
  18. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Un detalle: Si dentro de los campos hay caracteres especiales (comillas), quizás antes haya que pasar el valor por la función quotemeta() o alguna otra.
Última edición por explorer el 2006-03-30 13:52 @620, editado 1 vez en total
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

Notapor preiddy » 2006-03-30 12:39 @569

Muchisimas gracias a todos y en especial a explorer.

Ahora mismo me pongo a revisarlo y ya comentaré impresiones.

:lol:
preiddy
Perlero nuevo
Perlero nuevo
 
Mensajes: 70
Registrado: 2006-03-29 05:43 @280
Ubicación: Madrid, España

Siguiente

Volver a Básico

¿Quién está conectado?

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