[perl] Problema con regexp

Bolo Lacertus lacertus@servidor.unam.mx
Fri, 04 Dec 1998 19:17:17 -0600


Saludos!!!

Guau!, esa es una tarea digna de Perl y las expresiones regulares.

Adrian Galindo wrote:
> Todo esta bien cuando existe volumen (V111 al final) y paginas (P111),
> pero cuando falta alguno o los dos no coincide, me regresa:
> @100@^aASHEROVA-RM^b1971^cTEOR-MAT-FIZ^dV8-P255
> @100@AYALACASTANARES-A-1969-INFORME-FINAL-ESTUDI-P5
> @100@AYALAMILIAN-G-1974-VARIATIONAL-METHODS-V1
> @100@CARRASCO-L-1973-THESIS-U-CALIFORNIA
> @100@^aCHAGOYADESANCHE.V^b1977^cBIOCHEM-BIOPH-RES-CO^dV76-P804

Esto se comprende, simplemente no coinciden con la expresion regular y
tu programa, por no perder todo, solo saca lo que coincide.

Ok, veamos la expresion que tienes (sin comentarios porque me confunden
un poquitín)
Aunque sin ellos no habría entendido nada.
$linea=~s/^(.....)(\w+(?:-|\.)\w+)-(\d+)-(.*)-(\w\d+)(-\w\d+)
	/$1\^a$2\^b$3\^c$4\^d$5$6/x;  #Junta las varibles ncontradas 
print "$linea\n";
Ok, segun comentas, la ^b ^c y ^d son opcionales. 
Por simplicidad divido el proceso en varios pasos. 

#!/usr/bin/perl
#Programa para prueba de expresiones regualres

open(AE,"p.dat"); #aqui puse los datos :)
while($z=<AE>)
{
  chop $z;
  $x=$z;
  $a=$b=$c=$d=$e=$f="";
  $z=~s/^(.....)//;
  print "1 Encontre $1\n";
  $a=$1;
  if($z=~s/^(\w+(-|\.)\w+)-//)
  {
    print "2 Encontre $1\n";
    $b=$1;
  }
  if($z=~s/^(\d+)-//)
  {
    print "3 Encontre $1\n";
    $c=$1;
  }
  if($z=~s/^(.*)-//)
  {
    print "4 Encontre $1\n";
    $d=$1;
  }
  if($z=~s/^(\w\d+)//)	#este nunca sale, pero me imagino que por algo
esta.
  {
    print "5 Encontre $1\n";
    $e=$1;
  }
  if($z=~s/^(-\w\d+)//)
  {
    print "6 Encontre $1\n";
    $f=$1;
  }
  $z="$a\^a$b\^b$c\^c$d\^d$e$f";  #Junta las varibles ncontradas 
  print "$z\n$x\n";
}
close AE;

Esto me da mas o menos lo que pides, solo que al parecer el resultado 4
puede tener mas de un guion.
Para hacer que 4 tenga todo lo posible, lo que hago es dejarlo al final,
haciendo que 5 y 6 busquen antes y desde el final, de modo que queda:
(Bueno, también haciendo algunos ajustes adicionales)

#!/usr/bin/perl
#Programa para prueba de expresiones regualres

open(AE,"p.dat");
while($z=<AE>)
{
  chop $z;
  $x=$z;
  $a=$b=$c=$d=$e=$f="";
  $z=~s/^(.....)//;
  print "1 Encontre $1\n";
  $a=$1;
  if($z=~s/^(\w+(-|\.)\w+)-//)
  {
    print "2 Encontre $1\n";
    $b=$1;
  }
  if($z=~s/^(\d+)-//)
  {
    print "3 Encontre $1\n";
    $c=$1;
  }
  if($z=~s/(\w\d+)$//)
  {
    print "6 Encontre $1\n";
    $f=$1;
  }
  if($z=~s/-(\w\d+-)$//)
  {
    print "5 Encontre $1\n";
    $e=$1;
  }
  ($z=~s/\-$//); #quita posibles - de separación al final
  print "4 Encontre $z\n";  #este siempre se encuentra, es el resto de
la cadena original
  $d=$z;
  $z="$a\^a$b\^b$c\^c$d\^d$e$f";  #Junta las varibles ncontradas 
  print "$z\n$x\n";
}
close AE;

De esta forma interpreta como solicitas casi todo el archivo, la unica
dificultad que tiene es en el renglón:
@100@^aCARRASCO-L^b1973-THESIS-U-CALIFORNIA^c^d

Que divide como:
@100@^aCARRASCO-L^b1973^cTHESIS-U-CALIFORNIA^d

Pero la verdad no veo como diferenciar el 1973-THESIS de cosas como el
1971-TEOR, hsata estoy tentado a pensar que se te pasó y si devías
separarlos.

Bueno, espero no haber destripado demaciado tu cadena original y que lo
que pongo si te sea de alguna utilidad (igual y con mi tardanza ya me
ganaste a resolverlo).

Haciendo ejericios de aplicacion de cadenas regulares: Daniel Sol
-- 
Bolo Lacertus: lacertus@servidor.dgsca.unam.mx			==~\___\
http://132.248.71.81/cgi-bin/lacertus/hola			 =__vvvv
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCM/GCS/GE/GED d?>d+ s:+ a-->- C++>+++$ US/UI++ P++++$ L+ E- W+++ N o?
K- 
w--- !O !M V-- PS++ PE-- Y+ PGP+ t+ 5? X- R* tv-- b++>+++ DI+++ D+ G+
e+>++ 
h* r++(*) y+ 
------END GEEK CODE BLOCK------
--------- Pie de mensaje --------------------------------
Visite: http://tlali.iztacala.unam.mx/~randrade/perl.shtml
Cancelar inscripcion:
mail to: majordomo@tlali.iztacala.unam.mx
text   : cancelacion perl