[Résolu][Perl]faire un match sur une chaîne de caractères '\N'

faire un match sur une chaîne de caractères '\N' [Résolu][Perl] - Perl - Programmation

Marsh Posté le 02-06-2008 à 13:57:23    

Bonjour,
 
J'ai un fichier texte (un export sql) dans lequel, par défaut, les champs "null" sont une chaîne de caractères : \N (oui, c'est une chaîne de caractères, pas un caractère de contrôle...).
Dans un script Perl, je souhaite faire une recherche sur cette chaîne de caractères.
Je voudrais, en plus, mettre ce champ dans une variable ($null_export) puisque je le recherche dans plusieurs boucles.
Je n'arrive pas à mettre \N dans cette variable, alors que ça marche nickel si je met une chaîne de caractères quelconque tel que par exemple "toto" (j'ai mis NULL AS 'toto' dans la commande sql).
Mon code est sans doute pourri  :ange:  mais voici ce que j'ai actuellement :

Code :
  1. @champ = split (/:/, $_, -1);
  2.   $null_export = "toto";
  3.   if ($champ[1] =~ m/^$null_export$/) {
  4.     print STDERR "Le champ est vide!\n";
  5.   }


Qu'est-ce que je dois faire pour mettre \N?
Si je mets :
  $null_export = "\\N";
ou
  $null_export = "\\\N";
ou
  $null_export = '\\N';
ou
  $null_export = \N;
ça ne marche pas.
Même si je mets ces mêmes champs directement dans l'expression régulière (ex: if ($champ[1] =~ m/^"\\N"$/)), ça ne marche pas non plus. :pfff:  
Je suis à court d'idées et je n'arrive pas à trouver de réponse dans la doc (y'en a trop  :D ).
Qu'est-ce que c'est qui coince dans ce cas?
Merci  :)  
 
a+


Message édité par Rocks le 02-06-2008 à 16:30:23

---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 13:57:23   

Reply

Marsh Posté le 02-06-2008 à 14:57:15    

T'es certain du motif que tu cherches???
Normalement \N est utilisé avec charnames et une constante.
 
Bon maintenant, si c'est vraiment la chaine de caractère \N que tu cherches, il suffit de faire:

Code :
  1. $null_export='\N';


Message édité par anapajari le 02-06-2008 à 14:57:37

---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 02-06-2008 à 15:17:07    

Hello,
 
Merci pour tes suggestions  :)  
Ouaip, je suis certain du motif ;)
Je viens de faire quelques tests supplémentaires.
Si je mets :

Code :
  1. if ($champ[1] =~ m/^$null_export$/) {


ça ne marche pas  :pfff:  
Si je mets

Code :
  1. if ($champ[1] =~ m/$null_export/) {


ça marche  :sol:  
Le seul défaut, c'est que je ne vérifie pas qu'il n'y a que \N sur la ligne...
Pourquoi est-ce que le ^ et le $ font planter la requête? Y aurait-il des caractères cachés sur la ligne? :heink:  
 
a+


---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 15:25:19    

Argh, je viens de voir que si je mets "use warnings;" il me dit :
"Unrecognized escape \N passed through in regex"... :(


---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 15:46:58    

Pour être encore plus précis, ceci marche :
if ($champ[1] =~ m/$null_export$/) {
et ceci aussi :
if ($champ[1] =~ m/\\N$/) {
Ce n'est donc que le ^ devant le \N qui pose problème...
Incidemment, si j'utilise m/$null_export$/ ça me met l'erreur "Unrecognized escape..." même si je mets "\\N" dans $null_export alors que si je mets m/\\N$/ je n'ai plus cette erreur...


---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 15:56:52    

nan mais y'a un truc que je comprends pas :o
De ce que je vois tu lis un fichier ligne à ligne, tu splittes et regarde la valeur de ta deuxieme colonne.
Celle-ci doit strictement est identique à '\N' pour que tu déclenches une action.
Pourquoi utiliser une regex plutôt que:

Code :
  1. if ($champs[1] eq '\N'){


Voir avec un petit coup de chomp si néssaire ( mais je vois pas comment ça pourrait être le cas)


---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Marsh Posté le 02-06-2008 à 16:16:47    

c'est dans une regexp, il faut donc que tu fasses
$null_export = "\\\\N";  
avec 4 \ ce que tu n'as pas encore essayé :D
Ca va faire "\\N" comme valeur dans $null_export  
et donc va tester "\N " dans l'expression régulière.
A+,

Message cité 1 fois
Message édité par gilou le 02-06-2008 à 16:17:13

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 02-06-2008 à 16:24:42    

anapajari -> Oui, c'est à peu près ça, tu as bien compris  ;)  
Et ton code marche très bien. :jap:  Comme je le disais au début, il y avait de fortes chances pour que mon code soit pourri et ça s'est avéré être le cas.  :D  
Par contre, je fais le même test sur plusieurs dizaines de colonnes, donc j'aimerais mettre le champ testé dans une variable, pour n'appeler que la variable à chaque fois et j'aimerais aussi m'assurer qu'il n'y ait que \N dans le champ parce qu'il n'est pas impossible qu'il y ait un \N dans un champ non null (même si c'est peu probable, j'en conviens  :D ), d'où l'usage de ^ et $.
En fait, je me rends compte qu'il faudrait que je fasse une routine qui teste si un champ est nul et appeler ça à chaque fois plutôt que d'écrire le code du test à chaque fois mais bon, je débute en perl (j'ai commencé la semaine dernière  :D ) et je suis pas développeur de toutes façons, donc je fais toutes les erreurs possibles et même quelques unes qui sont à priori impossibles.  :D  
En tout cas merci beaucoup pour ton aide, ça m'a bien fait avancer.  :jap:  
 
a+

Message cité 1 fois
Message édité par Rocks le 02-06-2008 à 16:26:57

---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 16:26:33    

gilou a écrit :

c'est dans une regexp, il faut donc que tu fasses
$null_export = "\\\\N";  
avec 4 \ ce que tu n'as pas encore essayé :D
Ca va faire "\\N" comme valeur dans $null_export  
et donc va tester "\N " dans l'expression régulière.
A+,


Hello,
 
Je viens de voir ton message et je venais de faire exactement ce test : c'est exactement ça.  :jap:  
Je me suis rendu compte que ça ne donnait pas ce que je voulais en faisant un print de ma variable.
 
Merci beaucoup  :)  
 
a+


---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 16:29:22    

Juste pour donner le résultat final, voici ce que donne le code qui fonctionne :

Code :
  1. $null_export = '';
  2.   $null_export .= '^';
  3.   $null_export .= '\\\\N';
  4.   $null_export .= '$';
  5.   if ($champ[1] =~ m/$null_export/) {
  6.     print STDERR "Erreur!\n";
  7.     exit;
  8.   }


Merci beaucoup pour votre aide à tous les deux.  :jap:  
 
a+


Message édité par Rocks le 02-06-2008 à 16:31:03

---------------
J'ai cherché à chercher mais je n'ai rien pu trouver et pourtant, j'avais trouvé.
Reply

Marsh Posté le 02-06-2008 à 16:29:22   

Reply

Marsh Posté le 02-06-2008 à 16:48:47    

Rocks a écrit :

anapajari -> Oui, c'est à peu près ça, tu as bien compris  ;)
Et ton code marche très bien. :jap:  Comme je le disais au début, il y avait de fortes chances pour que mon code soit pourri et ça s'est avéré être le cas.  :D
Par contre, je fais le même test sur plusieurs dizaines de colonnes, donc j'aimerais mettre le champ testé dans une variable, pour n'appeler que la variable à chaque fois et j'aimerais aussi m'assurer qu'il n'y ait que \N dans le champ parce qu'il n'est pas impossible qu'il y ait un \N dans un champ non null (même si c'est peu probable, j'en conviens  :D ), d'où l'usage de ^ et $.


Oui et bien je confirme qu'il est absolument pas utile de faire une regex pour tester une valeur donnée.
Une sub me paraitrait un peu exagéré, aussi définirais-je plutôt une variable:

Code :
  1. use constant {
  2.  NULL   => '\N',
  3. };
  4. #...
  5. if ( $champ[1] eq NULL){
  6.     print STDERR "Erreur!\n";
  7.     exit;
  8. }
 

edit: s'pas bo comment t'as fait :o


Message édité par anapajari le 02-06-2008 à 16:49:15

---------------
Software and cathedrals are much the same - first we build them, then we pray.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed