[PERL: Expr. régulières]: Négation d'un mot [Fermé]

Signaler
Messages postés
23
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mai 2008
-
Messages postés
23
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mai 2008
-
Bonjour à tous,

Je suis en train de travailler sur des expressions régulières en PERL et j'ai besoin d'utiliser l'opérateur de négation non pas sur un ensemble de caractères (cad le [^...]) mais sur un mot entier.
Je m'explique :

Soit par exemple le fichier monExemple.txt suivant :

ceci est un fichier test, 
ceci est un fichier texte, 
ceci est un fichier avec des caractères.
Ceci est un fichier simple.

Je voudrais matcher uniquement les cas ou "fichier" est suivi de tout sauf de la chaine "texte", et le dans ce cas là entourer les patrons matchés par une balise (<balise>...</balise>), cad que je voudrais qqch comme ça :

ceci est un <balise>fichier test</balise>, 
ceci est un fichier texte, 
ceci est un <balise>fichier balisé</balise>.
Ceci est un <balise>fichier simple</balise>.


Je pensais donc à :

open(F, "monExemple.txt") 
	or die "PB : $!";

while ($ligne = <F>){

	if($ligne =~ /fichier [^texte]* /){ # ce que je voudrais dire ici c'est : si je matche "fichier" suivi de n'importe quoi SAUF "texte"
		$av=$`;
		$ap=$';
		$motif=$&;
		$motif =~ s/($motif)/<balise>$1<\/balise>/g;
		print "$av" . "$motif" . "$ap" . "\n";
	}
}
close (F);



sauf qu'ici la négation porte sur les caractères "t", "e", "x", "t", et "e" et non sur la chaine exacte "texte".

Donc si qqn avait une solution por m'aider ?
NB : sachant que je ne dois pas utiliser une solution du type : ($ligne !~ /fichier texte/)



Merci d'avance! (en espérant avoir été suffisamment clair..)

F Pignon

4 réponses

Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 542
Salut,

voici 2 exemples
lami20j@debian:~$ cat f_pignon
fichierdivers
fichiertexte
fichiernimportequoi
fichiertexte
fichierperl
lami20j@debian:~$ perl -ne 'print unless /^\w+(?=texte)/' f_pignon
fichierdivers
fichiernimportequoi
fichierperl
lami20j@debian:~$ perl -ne 'print if /^fichier(?!texte)/' f_pignon
fichierdivers
fichiernimportequoi
fichierperl
lami20j@debian:~$
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 542
Et dans un script
lami20j@debian:~$ cat f_pignon.pl
#!/usr/bin/perl
use strict;use warnings;

while(<DATA>){
  print if /fichier(?!texte)/;
}
__END__
fichierdivers
fichiertexte
fichiernimportequoi
fichiertexte
fichierperl
lami20j@debian:~$ perl f_pignon.pl
fichierdivers
fichiernimportequoi
fichierperl
lami20j@debian:~$
2ème variante
lami20j@debian:~$ cat f_pignon.pl
#!/usr/bin/perl
use strict;use warnings;

while(<DATA>){
  print unless /fichier(?=texte)/;
}
__END__
fichierdivers
fichiertexte
fichiernimportequoi
fichiertexte
fichierperl
lami20j@debian:~$ perl f_pignon.pl
fichierdivers
fichiernimportequoi
fichierperl
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 542
Et voici pour ton exemple (à toi d'adapter)
lami20j@debian:~$ cat f_pignon.pl
#!/usr/bin/perl
use strict;use warnings;

open F,"monExemple.txt"
    or die "PB : $!";

while (<F>){
  next unless /fichier\s+(?!texte)/;
  s#^(.*)(fichier.*)#$1<balise>$2</balise>#;
  print;
}
close (F);
__END__
lami20j@debian:~$ cat monExemple.txt
ceci est un fichier test,
ceci est un fichier texte,
ceci est un fichier avec des caractères.
Ceci est un fichier simple.
lami20j@debian:~$ perl f_pignon.pl
ceci est un <balise>fichier test, </balise>
ceci est un <balise>fichier avec des caractères.</balise>
Ceci est un <balise>fichier simple.</balise>
Messages postés
23
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mai 2008
1
Bonsoir lami20j,

Merci beaucoup pour ta réponse qui une fois de plus va bien m'aider (car ça marche très bien comme ça)

Par contre plus précisément, mon problème porte vraiment sur l'opérateur de négation sur un mot entier car je ne sais potentiellement pas le mot qui va être concerné par la ligne à ignorer.

Mon script est en fait un peu plus long que ça.
Je prends des patrons dans un fichier (c'est un fichier de règles syntaxiques) et je vérifie à l'aide de mon script si chacun de ces patrons matche dans mon fichier texte (qui contient des mots étiquetés).

Exemple simple:

Dans mon fichier de règles :

règle1 : mot_TagA mot_TagB
règle2 : mot_TagA mot_TagB mot_TagC
règle3 : mot_TagA mot_TagD
etc.


Dans mon fichier texte

mot1_TagA  mot2_TagE  mot3_TagB  mot4_TagA  mot5_TagB  mot6_TagF, ...


et je dois obtenir ça (d'après la règle 1 par exemple):

mot1_TagA  mot2_TagE  mot3_TagB  <balise>mot4_TagA  mot5_TagB</balise>  mot6_TagF, ...



Mes règles sont donc sous forme d'expressions régulières et je veux pouvoir utiliser des règles du type :

mot_Tag-quelconque mot_TagB mot_TagC "suivi de n'importe quoi sauf 'mot_TagE' "


que je voudrais écrire comme ça:

mot_[^ ]+ (mot_TagB )+(mot_TagC )+[^mot_TagE]+



D'où la nécessité de pouvoir faire porter la négation sur un mot entier, mais peut être est ce trop "tordu"...

Si tu vois comment je pourrais procéder ?

Merci encore
Messages postés
21331
Date d'inscription
jeudi 4 novembre 2004
Statut
Modérateur, Contributeur sécurité
Dernière intervention
30 octobre 2019
3 542
/fichier(?!texte)/;
Ben, justement, l'utilisation de test avant négatif permet de faire ça
Le teste avant négatif permet de ne pas réussir sur la droite



Messages postés
23
Date d'inscription
mardi 25 septembre 2007
Statut
Membre
Dernière intervention
29 mai 2008
1
ok merci beaucoup, dsl j'allais justement te demander ce que faisais cette ligne..

J'ai ma réponse :)


Merci encore