• Publicidad

Opcionalidad y contextos en las expresiones regulares

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

Opcionalidad y contextos en las expresiones regulares

Notapor ana gonzález ledesma » 2009-02-15 06:43 @321

Hola, tengo un par de preguntas sobre el uso de paréntesis en las expresiones regulares.

Estoy buscando una serie de palabras para hacer sustituciones, pero solo quiero hacer la sustitución cuando la palabra encontrada satisfaga determinadas condiciones contextuales. En este caso lo que rodea a la palabra que quiero sustituir es solo un contexto, no forma parte de la sustitución.

Mis preguntas son las siguientes.

En el siguiente programa
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach $palabra (@listapalabras) {

    while (<>) {
        if (s/($contexto) ($palabra) ($contexto/)<md>$2<\/<md>/) {print;} #
    }
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4

a mí me gustaría conseguir expresar en la anterior expresión regular las siguientes cosas:
  1. que $contexto es sólo un contexto, que debe tenérselo en cuenta para $palabra pero no lo quiero memorizar, ni lo quiero sustituir, lo quiero conservar tal y como está. Solo quiero que lo lea.
  2. los paréntesis sirven para memorizar, y también para agrupar. Pero mi pregunta es si también expresan opcionalidad. Porque lo que yo en realidad quiero expresar en la expresión regular son las siguientes posibilidades, y me gustaría saber si existe una manera mínima y elegante de expresarlas todas.

    La sustitución se hará siempre que:
    Sintáxis: [ Descargar ] [ Ocultar ]
    Using perl Syntax Highlighting
    if /$contexto $palabra/
    if /$palabra $contexto/
    if /$contexto $palabra  $contexto/
    Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Y también me gustaría saber cómo puedo expresar si la palabra no se encuentra en ninguno de estos tres casos , sustitúyela por <no>palabra<no>. ¿Cómo niego las variables contextuales en este caso?

He pensado en varias soluciones y ninguna buena.

La primera que pensé fue:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if s/($contexto) ($palabra) ($contexto)/<md>$palabra<md>/
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
pero ¿si no quiero que me sustituya $contexto, $palabra seguiría siendo $2?

Además, en el caso de que los paréntesis también signifiquen que pueden aparecer o no (y no solo sirvan para memorizar) esta expresión así escrita contempla la posibilidad de que $palabra aparezca solo también, y ese es precisamente el caso en que debe etiquetarse de otra manera.

La otra posibilidad que he pensado es utilizando |. Por ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
/$contexto $md | $md $contexto | $contexto $md $contexto/
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
pero entonces aquí me encuentro con el problema de cómo memorizo $md, si en cada posibilidad es o $1 o $2.

He estado mirando en vuestros manuales de expresiones regulares pero no habla de estos problemas.

Es difícil buscar en la documentación, cuando tienes un problema o una duda muy concreta, dónde se encuentra la sección específica que se podría aplicar a resolver tu problema; si alguno de vosotros la sabe ¿me los podríais decir en un momento por favor? Mientras, yo sigo buscando.

Gracias.
ana gonzález ledesma
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-11-02 10:25 @475

Publicidad

Notapor zipf » 2009-02-15 08:15 @385

Hola, Ana.

Consulta la sección "Looking ahead and looking behind" del tutorial de expresiones regulares incluido en la documentación de Perl: perlretut.

Por ejemplo, puedes escribir la expresión regular de la sustitución así:
(?<=\b$contexto_pre\s+)$palabra(?=\s+$contexto_post\b)

Estas construcciones (positive lookbehind y positive lookahead) no consumen texto.

Esto se puede complicar un poco más si también quieres tener en cuenta los signos de puntuación.

La opcionalidad la puedes especificar mediante el cuantificador "?" (o "*").

No entiendo bien tu programa. No hace falta que captures $palabra, porque ya la tienes (es el argumento actual del bucle foreach), ¿no?

(No estoy seguro, pero creo que también te interesaría cambiar el orden de foreach y while)

Creo que para empezar deberías utilizar varias cláusulas if para cubrir los distintos casos en lugar de buscar una expresión compacta. Ya habrá tiempo para optimizaciones cuando todo funcione.

Por ejemplo (ojo, no he probado el código; lo escribo para dar la idea...):

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if (
    /(?<=\b$contexto_pre\s+)$palabra\b/i
   ||
   /\b$palabra (?=\s+$contexto_post\b/i
  ) {
       print "<md>$palabra</md>";
 } else {
       print "<no>$palabra<no>";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Esto se puede expresar de forma más compacta con el operador ternario "?:", pero en este caso concreto no creo que aporte mucho y empeora la legibilidad del programa.

Estos módulos de CPAN también te pueden dar ideas:

Text::Context::EitherSide
Text::Context

Saludos,
Enrique
zipf
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2008-11-24 08:07 @380

Notapor explorer » 2009-02-15 09:26 @435

Efectivamente, los paréntesis, además de capturar, pueden servir para agrupar opciones.

Para evitar que los paréntesis hagan capturas, puedes ponerlo así: (?:...). Lo mismo en el caso de opciones: (?:...|...|...).

Si un par de paréntesis, es opcional, como te comentaba zipf, le pones un '?' al final: (...)?. Y luego tenerlo en cuenta a la hora de saber a qué número de captura corresponde.

Perl 5.10 tiene mejoras en la captura de paréntesis, facilitando el darles nombres a medida de que se van capturando, por lo que no es necesario llevar la cuenta del número de paréntesis. Ver perlre.

Un detalle: en las opciones múltiples, empieza siempre buscando por la opción más interesante o probable. Si estás buscando por que la $palabra esté rodeada por $contexto, entonces ese es el primer caso a analizar:
/$contexto $md $contexto | $contexto $md | $md $contexto/ (incluso en el caso de if() en cascada).

Finalmente, decir que hay una cuestión así en las perlfaq6: Can I use Perl regular expressions to match balanced text?, salvo que además estás planteando los casos de que uno de los contextos no esté. En ese caso no te vale las soluciones de "balanced", y la cosa se complica un poco más.

¿Un ejemplo?
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor explorer » 2009-02-15 09:38 @443

zipf escribiste:(?<=\b$contexto_pre\s+)$palabra(?=\s+$contexto_post\b)

Aquí hay un problema, zipf: el "look behind" solo funciona con expresiones regulares de ancho fijo: no puedes poner el "\s+".
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor ana gonzález ledesma » 2009-02-15 10:51 @494

Gracias a los dos. No solo por las propuestas sino también por recomendarme la documentación específica en la que se habla de la duda que tengo en concreto. Me habéis ahorrado muchas horas. Con la enmienda final no me queda claro si puedo poner \s o no, el término ancho fijo no lo había escuchado nunca, no sé exactamente qué significa.

En lo que respecta a las sustituciones con dolar, en este caso en concreto (que no lo voy a usar pero que me sirve para lo que quiero preguntar)
s/(?<=\b$contexto_pre\s+)($palabra)(?=\s+$contexto_post\b)/<md>$1<md>/

$1 sería finalmente $palabra, ya que si no he comprendido mal, los paréntesis precedente y posterior no se memorizan, ¿no? (ya sé, moderador, que me has recomendado algo en concreto para esto).

Bien. Aprovechando el tirón, y la buena voluntad, me gustaría hacer una pregunta relacionada con la memoria de las expresiones regulares. El contexto a la derecha de mi expresión regular en el fondo es una lista de cuatrocientas palabras. Yo he decidido incluirla en la expresión regular de esta manera. Leo la lista de palabras de un archivo, la meto en una array y luego construyo con un join() con | una expresión regular de opcionalidad que será metida finalmente en una variable.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub cargaListaOtherMd () {
   open(LISTATOTALMDS, $LISTATOTALMDS) || die $!;
   while (<LISTATOTALMDS>) {
    chomp;
    #print "$_\n";
    push(@othermarcadores, $_);
   
                   }
   close(LISTATOTALMDS);
                          }      


sub preparaOtherMd() {
  $othermd = join("|", reverse sort @othermarcadores);

  #print "$othermd\n";
                     }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


el contexto a la derecha sería $contexto_derecha= ($othermd|$signosdepuntuacion);

De esta manera el programa principal queda más limpio, no tengo que hacer un bucle, para recorrer la lista dentro de la expresión regular (algo que por otra parte no sabría hacer).
Con lo que al final la cosa quedaría con este aspecto sencillo y claro:
declaro subrutinas...

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach $palabra  (@listapalabras)

{
 while (<micorpusdetextos>)

{
  if /(?<=$contextoderecha)$md((?=contextoizquierad)/<md>$1<$md>/;
 y los demás if
y el else.

}
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


¿Esto es una buena solución al problema? ¿Aliviaría algo usar una referencia a $othermds en términos de memoria o como se dice en italiano "questo non centra niente" (esto no tiene nada que ver)?
ana gonzález ledesma
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-11-02 10:25 @475

Notapor explorer » 2009-02-15 12:22 @557

Lo del ancho fijo se refiere a que no estamos indicando cuántos caracteres comprende esa expresión regular. Si pongo simplemente \s sé que estoy esperando un solo carácter espacio. Si pongo \s{12} entonces estoy esperando 12 caracteres. Pero si pongo \s+ estoy diciendo "uno o más", pero no "cuántos". En los "look behind" no se pueden poner expresiones de ese último tipo.

Como te ha dicho antes zipf, los "look behind" y "look ahead" no capturan.

En cuanto a la forma de crear la expresión regular, no entiendo el porqué usas reverse() y sort(), salvo que sea por una buena razón.

Sí que se suele usar este método para crear una condición de opcionalidad. En algunos hilos de estos foros ya los hemos usado. Quizás, yo usaría qr() para la variable $othermd, ya que lo que almacena es una expresión regular, y se aprecia una mejora de velocidad.

Tu problema se parece un poco a definir una semántica, pero, insisto, me gustaría ver un ejemplo.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14482
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor zipf » 2009-02-15 12:38 @568

explorer escribiste:
zipf escribiste:(?<=\b$contexto_pre\s+)$palabra(?=\s+$contexto_post\b)

Aquí hay un problema, zipf: el "look behind" solo funciona con expresiones regulares de ancho fijo: no puedes poner el "\s+".


Es verdad. Se puede hacer con \K, pero sólo funciona en Perl 5.10. O con el módulo Regexp::Keep en 5.8.
zipf
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2008-11-24 08:07 @380

Notapor zipf » 2009-02-15 13:32 @605

zipf escribiste:
explorer escribiste:
zipf escribiste:(?<=\b$contexto_pre\s+)$palabra(?=\s+$contexto_post\b)

Aquí hay un problema, zipf: el "look behind" solo funciona con expresiones regulares de ancho fijo: no puedes poner el "\s+".


Es verdad. Se puede hacer con \K, pero sólo funciona en Perl 5.10. O con el módulo Regexp::Keep en 5.8.


A título de curiosidad, el motor de expresiones regulares de .NET Framework sí admite lookbehind con expresiones de longitud variable.
zipf
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2008-11-24 08:07 @380

Notapor zipf » 2009-02-15 21:48 @950

ana gonzález ledesma escribiste:¿Esto es una buena solución al problema? ¿Aliviaría algo usar una referencia a $othermds en términos de memoria o como se dice en italiano "questo non centra niente" (esto no tiene nada que ver)?


Hola Ana

No estoy seguro de haber entendido el planteamiento inicial, pero yo atacaría este problema de otra manera:

Para empezar, insertaría la lista de palabras en un hash convirtiéndolas
a minúsculas con lc() (o a mayúsculas con uc(), lo que prefieras).
Después, para cada frase del corpus, haría lo siguiente:

1) Extraer las palabras (tokenizar, vamos) e insertarlas en un array convirtiéndolas previamente a minúsculas.

2) Recorrer con foreach el array y comprobar para cada palabra si
existe en el hash. En caso afirmativo, aplicar el tratamiento de belleza a la cadena:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
if ($words{$word}) {

    $string =~ s/\b$context\s+\K($word)\b/<md>$1<\/md>/ig;
    $string =~ s/\b($word)(?=\s+$context\b)/<md>$1<\/md>/ig;
    $string =~ s/(?<![>])\b($word)\b(?![<])/<no>$1<\/no>/ig;

    print "$string\n";
}
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Por ejemplo, para:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my $string = "Just    another text hacker. Another just another... And yet another...";
my $word = 'another';
my $context = 'just';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


el resultado es:
Sintáxis: [ Descargar ] [ Ocultar ]
  1. Just <md>another</md> text hacker. <md>Another</md> just <md>another</md>... And yet <no>another</no>... 


Saludos,
Enrique
zipf
Perlero nuevo
Perlero nuevo
 
Mensajes: 10
Registrado: 2008-11-24 08:07 @380

Notapor ana gonzález ledesma » 2009-02-16 14:38 @651

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:

Sintáxis: [ Descargar ] [ Ocultar ]
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.

Sintáxis: [ Descargar ] [ Ocultar ]
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:
Sintáxis: [ Descargar ] [ Ocultar ]
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.010 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.
ana gonzález ledesma
Perlero nuevo
Perlero nuevo
 
Mensajes: 17
Registrado: 2006-11-02 10:25 @475

Siguiente

Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: Bing [Bot] y 0 invitados