Hola, de nuevo. Os escribo porque sigo sin solucionar el problema.
Me gustaría primero de todo, ya que explorer me lo ha pedido explícitamente, explicar en qué consiste el programa que estoy haciendo.
Bien. Tengo un corpus, esto es, una colección de textos. Me interesa estudiar el comportamiento de determinadas palabras típicas del lenguaje oral, como por ejemplo, la palabra "bueno". Muchas de estas palabras, denominadas por la lingüística, marcadores del discurso, tienen en el lenguaje más de una categoría. Así, "bueno" tiene la categoría de marcador pero también la de adjetivo. Bien. Para etiquetar la categoría de estas palabras de manera automática yo he diseñado unas reglas contextuales que son las expresiones regulares de ayer. De tal manera que, "bueno" será marcador discursivo cuando tenga:
Using perl Syntax Highlighting
$otromarcador|$signodepuntuacion) $marcador otromarcador
|$signodepuntuacion)Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Este es un contexto seguro.
Luego hay contextos probables.
Using perl Syntax Highlighting
$otromarcador|$signodepuntuacion) $marcador unapalabracualquiera
unapalabracualquiera
$marcador $otromarcador|$signodepuntuacion)Coloreado en 0.001 segundos, usando
GeSHi 1.0.8.4
Bien, el programa hace lo siguiente:
Coge la lista de marcadores ambiguos y los ordena y los mete en una lista.
Coge otra lista de marcadores y los ordena y los mete en otra lista (los ordena para que coja primero "y ya" antes que ya, y con esto contesto a tu pregunta explorer de ayer).
Luego abre un directorio.
Hace una serie de sustituciones en los archivos que tienen que ver con las marcas prosódicas (que son al lenguaje oral lo que los signos de puntuación son al lenguaje escrito) que me daban muchos problemas en las expresiones regulares y los mete en la variable $signos.
Recorre la lista de marcadores ambiguos, si encuentra un marcador en un contexto seguro, hace la sustitución e imprime la línea en una archivo con el nombre del marcador para futura evaluación de que la regla ha funcionado. Este archivo está dentro de un directorio llamado "seguro".
Después lo mismo con los contextos probables.
Y después lo mismo con los contextos improbables.
Y al final imprime todos los archivos en un directorio CORPUS_SALIDA.
Bien, este es el programa:
Using perl Syntax Highlighting
#title: standforddream.pl
use strict
;
use locale
;
#corre las subrutinas primero
cargaLista
();
cargaListaOtherMd
();
preparaOtherMd
();
#preparaCorpus ();
our @marcadoresambiguos;
our $marcadorambiguo;
our @othermarcadores;
our $othermd;
our $directorio_entrada = './coralrom/'; # ATENCION: En windows creo que las barras son al revés \
our $directorio_salida = './coralromconambiguosetiquetados/';
#########################################
opendir D
, $directorio_entrada or die "Error en opendir";
my $nombre_archivo;
my @lista_archivos;
#############################################
while ($nombre_archivo = readdir(D
)) {
if ($nombre_archivo =~ /\.txt$/) { # Solo quiero los que acaben en .txt p.e.
#print "$nombre_archivo\n";
push @lista_archivos, $nombre_archivo;
}
}
closedir D
; # Ya los tengo en @lista_archivos
##################################################3
foreach our $archivo (@lista_archivos) {
my $archivo_entrada = $directorio_entrada.$archivo;
our @lineas;
open F
, "<$archivo_entrada" or die "Problemas en archivo de entrada $archivo_entrada $!";
while (<F>) { # lee linea a linea
# lo que sea, p.e. cambia as por es
#chomp;
#s/\r//;
if ($_=~/^\
*/) {
s/\?/INTERROGATION/g;
s/\[\/\]/REFORMULADORUNO/g;
s/\[\/\/\]/REFORMULADORDOS/g;
s/\[\/\/\/\]/REFORMULADORTRES/g;
s/\/\//DOSBARRAS/g;
s/\//UNABARRA/g;
s/\.\.\./TRESPUNTOS/g;
s/\:/DOSPUNTOS/g;
s/\+/INTERRUPCION/g;
s/#/PAUSE/g;
s/\[<\]//g;
s/<//g;
s/>//g;
s/\&/AMPERSAN/g;
s/\&/AMPERSAN/g;
s/ / /g;
s/ / /g;
#############################
my $barra = "UNABARRA"; #tone unit /
my $dosbarras = "DOSBARRAS"; #final de utterance //
my $r1 = "REFORMULADORUNO"; #reformuladores de uno, dos y tres. [/] [//] [///], porque no sé qué versión voy a utilizar porsiaca
my $r2 = "REFORMULADORDOS";
my $r3 = "REFORMULADORTRES";
my $question = "INTERROGATION"; #final de utterance interrogación ?
my $suspension = "TRESPUNTOS"; #final de utterances suspensión ...
#my $overlaps = '[<]'; #asegurarte de que es así qué vas a hacer con los solapamientos los quitas?
my $ppioturn = "DOSPUNTOS"; #ppio de turno : ¿esto es un metacaracter?
my $pause = "PAUSE"; #pausa larga ¿es metacaracter?
my $interrup = "INTERRUPCION"; #interrupción, + o +/. porque todavía no sé qué versión voy a utilizar.
our $signos = "$dosbarras|$barra|$r1|$r2|$r3|$question|$suspension|$ppioturn|$pause|$interrup";
#print "$signos\n";
#################################
foreach $marcadorambiguo (@marcadoresambiguos)
{
#print "$marcadorambiguo\n";
if ($_=~ s/(?<=$signos) ($marcadorambiguo) (?=\
s$signos\
s)/<MD>$marcadorambiguo<\
/MD
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/SEGURO/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #fin primer if
if ($_=~ s/(?<=\
s$othermd\
s) ($marcadorambiguo) (?=\
s$signos\
s)/<MD>$1<\
/MD
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/SEGURO/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #segundo if
if ($_=~ s/(?<=\
s$signos\
s) ($marcadorambiguo) (?=\
s$othermd\
s)/<MD>$1<\
/MD
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/SEGURO/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #tercer if
if ($_=~ s/(?<=\
s$othermd\
s) ($marcadorambiguo) (?=\
s$othermd\
s)/<MD>$1<\
/MD
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/SEGURO/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #cuarto if
if ($_=~ s/(?<=!\
s$othermd\
s|\
s$signos\
s) ($marcadorambiguo) (?=\
s$signos\
s|\
s$othermd\
s)/<MD>$1<\
/MD
>/ig
){ #(?<=!\s$othermd\s|\s$signos\s)ESTO SE PUEDE PONER ASÍ??? PARA AHORRAR?
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/PROBABLE/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #quinto if
if ($_=~ s/(?<=\
s$othermd|$signos\
s) ($marcadorambiguo) (?=!$signos|$othermd)/<MD>$1<\
/MD
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/CTXTPROBABLE/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #sexto if
if ($_=~ s/(?<=!\
s$othermd|$signos\
s) ($marcadorambiguo) (?=!$signos|$othermd)/<OTRACATEGORIA>$1<\
/OTRACATEGORIA
>/ig
){
#print "--- he encontrado $md en la línea $_\n";
open(SALIDA_EVALUACION
,">>./SALIDA_EVALUACION/CTXCATEGORIAL/$marcadorambiguo.txt") || die ("$marcadorambiguo no se ha abierto");
print SALIDA_EVALUACION
"$archivo$_\n";
close (MARCADOR
);
} #sexto if
} #fin foreach lista ambiguos
#sustituir por $1 cuando estés segura de que los contextos inmoviles no memorizan
} # FIN DEL while
######################################
push @lineas, $_; # y lo guardo en @lineas
} #fin foreach archivo
close F
;
# y para la salida
my $archivo_salida = $directorio_salida.$archivo;
print "Haciendo: $archivo_salida\n";
open G
, ">$archivo_salida" or die "Problemas con el archivo de salida $archivo_salida $!";
print G
@lineas;
close G
;
}
####################################3
sub preparaOtherMd
() {
$othermd = join("|", reverse sort @othermarcadores);
#print "$othermd\n";
}
#################################
sub cargaListaOtherMd
() {
open(LISTATOTALMDS
, "listatotalyredefinitivamdsencontrados.txt") || die $!;
while (<LISTATOTALMDS>) {
chomp;
s/\r//;
#print "$_\n";
push(@othermarcadores, $_);
}
close(LISTATOTALMDS
);
#@othermarcadores = sort {length($b)<=>length($a) || $a <=> $b} (@othermarcadores);
#da el siguiente error sort subroutine didn't return a numeric value
}
#foreach $othermd (@othermarcadores)
#{print "$othermd\n"; }
################################
sub cargaLista
() {
open(LISTA
, "listafinalambiguoscategoriales.txt") || die $!;
while (<LISTA>)
{
chomp;
s/\r//;
#print "$_\n";
push(@marcadoresambiguos, $_);
}
close(LISTA
);
@marcadoresambiguos = sort {length($b)<=>length
($a) || $a <=> $b} (@marcadoresambiguos);
}
#foreach $marcadorambiguo (@marcadoresambiguos)
#{print "$marcadorambiguo\n"; }Coloreado en 0.004 segundos, usando
GeSHi 1.0.8.4
El mensaje de error que me da Perl cuando paso el programa es el siguiente:
- Código: Seleccionar todo
variable length lookbehind not implemented in regex m/?<=DOSBARRAS|UNABARRA, ...
En la línea 93, esto es, justo cuando empieza la primera expresión.
En fin.
Si alguien se aburre, y tiene ganas de emplear sus conexiones neuronales en una humilde linguista pues ya sabe.
Una última cosa, en las últimas expresiones regulares he puesto para optimizar
(?<=!\s$othermd|$signos\s) pero no sé si esto se puede hacer o no, y en la documentacion que ayer mi dio zipf no sale.
Bueno, pues nada, ya doy las gracias por adelantado a quien se introduzca en el arduo mundo del procesamiento del lenguaje natural.