IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SAS Base Discussion :

REGEX : Problème avec les assertions arrières [DATA]


Sujet :

SAS Base

  1. #1
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut REGEX : Problème avec les assertions arrières
    Bonjour,

    je réalise des REGEX pour normaliser des chaines de caractères complexes présentes dans mes données.

    J'ai écrit un bout de code avec des assertions arrières qui pose pas de problèmes

    voici un exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    data a;
    length var $40;
    var='totoAB CD';output;
    var='totoA CD';output;
    var='*V* *D3 *I*TiTiToTo*I*';output;
    var='*I* *D3 *I*Pif&Paf*I*';output;
    var='*IN* *D3 *I*Pif&Paf*I*';output;
    var='*V* *D3 TaTa';output;
    var='*N* *D3 *I*TiTiToTo*I*';output;
    run;
     
    data b; set a;
    retain regex;
    if _n_=1 then do;
    regex=prxparse('s/(?<=[VIL]\*\s\*(?:D[1-9A]|L[1-4]))\s\*[VIL]\*([^\*]+)\*[VIL]\*\s/# $1 /');
    end;
    if prxmatch(regex,var) then var2=prxchange(regex,1,var);
    run;
    proc print data=b;run;
    qui me fait quelques transformations (cf ci dessous)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                         Obs    var                       regex          var2
     
                          1     totoAB CD                   1
                          2     totoA CD                    1
                          3     *V* *D3 *I*TiTiToTo*I*      1      *V* *D3# TiTiToTo
                          4     *I* *D3 *I*Pif&Paf*I*       1      *I* *D3# Pif&Paf
                          5     *IN* *D3 *I*Pif&Paf*I*      1
                          6     *V* *D3 TaTa                1
                          7     *N* *D3 *I*TiTiToTo*I*      1
    Les transformations sont déterminées par les balises *caractère*

    Je voulais faire des variantes à deux caractères de mes balises*

    Par exemple je voulais que la regex reconnaisse non seulement
    *V* , *I* et *L* mais également *VN* , *IN* et *LN*

    Donc je me suis dit, c'est simple il suffit de remplacer la description de tes balises qui s'écrivent en [VIL]\* ou \*[VIL]\*
    par [VIL]N?\* ou \*[VIL]N?\*

    et là à ma grande surprise SAS n'accepte pas à la compilation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    data b; set a;
    retain regex;
    if _n_=1 then do;
    regex=prxparse('s/(?<=[VIL]N?\*\s\*(?:D[1-9A]|L[1-4]))\s\*[VIL]N?\*([^\*]+)\*[VIL]N?\*\s/# $1 /');
    end;
    if prxmatch(regex,var) then var2=prxchange(regex,1,var);
    run;
    ce qui donne en log

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
     
    ERROR: Variable length lookbehind not implemented before HERE mark in regex
           m/(?<=[VIL]N?\*\s\*(?:D[1-9A]|L[1-4]))\s\*[VIL]N?\*([^\*]+)\*[VIL]N?\*\s << HERE /.
     
    ERROR: The regular expression passed to the function PRXPARSE contains a syntax error.
    NOTE: Argument 1 to function PRXPARSE at line 9601 column 7 is invalid.
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=totoAB CD regex=. var2=  _ERROR_=1 _N_=1
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=totoA CD regex=. var2=  _ERROR_=1 _N_=2
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=*V* *D3 *I*TiTiToTo*I* regex=. var2=  _ERROR_=1 _N_=3
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=*I* *D3 *I*Pif&Paf*I* regex=. var2=  _ERROR_=1 _N_=4
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=*IN* *D3 *I*Pif&Paf*I* regex=. var2=  _ERROR_=1 _N_=5
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=*V* *D3 TaTa regex=. var2=  _ERROR_=1 _N_=6
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9603 column 4 is invalid.
    var=*N* *D3 *I*TiTiToTo*I* regex=. var2=  _ERROR_=1 _N_=7
    NOTE: Mathematical operations could not be performed at the following places. The results of the
          operations have been set to missing values.
          Each place is given by: (Number of times) at (Line):(Column).
          1 at 9601:7   7 at 9603:4
    NOTE: There were 7 observations read from the data set WORK.A.
    NOTE: The data set WORK.B has 7 observations and 3 variables.
    NOTE: Compressing data set WORK.B increased size by 100.00 percent.
          Compressed is 2 pages; un-compressed would require 1 pages.
    NOTE: DATA statement used (Total process time):
          real time           0.01 seconds
          cpu time            0.01 seconds
    Je me dit ok c'est le ? qui pose problème donc j'ai remplacé le
    ([VIL]N?) par (?:[VIL]N|[VIL])

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    data b; set a;
    retain regex;
    if _n_=1 then do;
    regex=prxparse('s/(?<=(?:[VIL]N|[VIL])\*\s\*(?:D[1-9A]|L[1-4]))\s\*(?:[VIL]N|[VIL])\*([^\*]+)\*(?:[VIL]N|[VIL])\*\s/# $1 /');
    end;
    if prxmatch(regex,var) then var2=prxchange(regex,1,var);
    run;
    proc print data=b;run;
    etv là paf ! même problème

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
     
    ERROR: Variable length lookbehind not implemented before HERE mark in regex
           m/(?<=(?:[VIL]N|[VIL])\*\s\*(?:D[1-9A]|L[1-4]))\s\*(?:[VIL]N|[VIL])\*([^\*]+)\*(?:[VIL]N|[VIL])
           \*\s << HERE /.
     
    ERROR: The regular expression passed to the function PRXPARSE contains a syntax error.
    NOTE: Argument 1 to function PRXPARSE at line 9609 column 7 is invalid.
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=totoAB CD regex=. var2=  _ERROR_=1 _N_=1
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=totoA CD regex=. var2=  _ERROR_=1 _N_=2
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=*V* *D3 *I*TiTiToTo*I* regex=. var2=  _ERROR_=1 _N_=3
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=*I* *D3 *I*Pif&Paf*I* regex=. var2=  _ERROR_=1 _N_=4
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=*IN* *D3 *I*Pif&Paf*I* regex=. var2=  _ERROR_=1 _N_=5
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=*V* *D3 TaTa regex=. var2=  _ERROR_=1 _N_=6
    NOTE: Argument 1 to the function PRXMATCH is missing.
    ERROR: Argument 1 to the function PRXMATCH must be a positive integer returned by PRXPARSE for a
           valid pattern.
    NOTE: Argument 1 to function PRXMATCH at line 9611 column 4 is invalid.
    var=*N* *D3 *I*TiTiToTo*I* regex=. var2=  _ERROR_=1 _N_=7
    NOTE: Mathematical operations could not be performed at the following places. The results of the
          operations have been set to missing values.
          Each place is given by: (Number of times) at (Line):(Column).
          1 at 9609:7   7 at 9611:4
    NOTE: There were 7 observations read from the data set WORK.A.
    NOTE: The data set WORK.B has 7 observations and 3 variables.
    NOTE: Compressing data set WORK.B increased size by 100.00 percent.
          Compressed is 2 pages; un-compressed would require 1 pages.
    NOTE: DATA statement used (Total process time):
          real time           0.00 seconds
          cpu time            0.00 seconds
    or à regarder mon code, j'ai déjà dans l'assertion arrière une expression similaire qui ne pose pas de problèmes à la compilation Je n'y comprend pas grand chose, où se situe le problème ?

  2. #2
    Rédacteur

    Homme Profil pro
    SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Inscrit en
    Avril 2009
    Messages
    2 497
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : SAS ALLIANCE SILVER. Consultant et formateur SAS et Cognos.
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2009
    Messages : 2 497
    Points : 6 064
    Points
    6 064
    Par défaut
    pourquoi tu fais des assertions arrières ?

    Pourquoi tu n'attrapes pas déjà ce qui est entre deux * par _reg_etoile= prxparse('/*(.+)*/i'); pour voir déjà ?

  3. #3
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Pourquoi je fais des assertions arrières ?

    Parce que je fais de la grammaire !

    Le résultat obtenu dans la première proc print est bien celui que je veux dans les cas

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
                          3     *V* *D3 *I*TiTiToTo*I*      1      *V* *D3# TiTiToTo
                          4     *I* *D3 *I*Pif&Paf*I*       1      *I* *D3# Pif&Paf
    Je voudrais aussi en même temps

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
                          5     *IN* *D3#  Pif&Paf      1
    mais ne surtout rien toucher aux autres.
    Il y a des règles bien spéciales qui se cache derrière cette expression régulière.
    Il s'agit d'explorer une variable texte d'adresse en regroupant ses différentes composantes par catégories pertinentes.

    Pour comprendre un peu
    Par exemple

    6 RUE DE LA MONTEE DU FORT RESIDENCE LE RICHELIEU
    LA RESIDENCE DU QUAI 6 RUE DE LA LIBERTE
    ALLEES DES RESIDENCES FLEURIES

    Elle se "dépiotte" classiquement avec des mots clés structurants présent dans les adresses comme "RUE" , "MONTEE" , "RESIDENCES" , "QUAI" , "ALLEES"

    6 RUE DE LA MONTEE DU FORT RESIDENCE LE RICHELIEU
    LA RESIDENCE DU QUAI 6 RUE DE LA LIBERTE
    ALLEES DES RESIDENCES FLEURIES

    Seulement à priori on ne sait pas vraiment ou couper...
    Donc j'essaye de former des mots grâce aux articulations

    Premièrement je met mes balises

    6 *V*RUE*V* DE LA *V*MONTEE*V* DU *L*FORT*L* *I*RESIDENCE*I* LE RICHELIEU
    LA *I*RESIDENCE*I* DU *V*QUAI*V* 6 *V*RUE*V* DE LA LIBERTE
    *V*ALLEES*V* DES *L*RESIDENCES*L* FLEURIES

    ensuite je réduis les articulations

    6 *V*RUE*V* *D1 *V*MONTEE*V* *D2 *L*FORT*L* *I*RESIDENCE*I* *L1 RICHELIEU
    *L2 *I*RESIDENCE*I* *D2 *V*QUAI*V* 6 *V*RUE*V* *D1 LIBERTE
    *V*ALLEES*V* *D3 *L*RESIDENCES*L* FLEURIES

    Je vous passe les étapes, et à la fin je dois arriver à

    6 RUE DE_LA_MONTEE_DU_FORT RESIDENCE LE_RICHELIEU
    LA RESIDENCE DU_QUAI 6 RUE DE_LA_LIBERTE
    ALLEES DES_RESIDENCES_FLEURIES

    Mais pour cela je dois désactiver dans certains cas certains balises préalablement mises
    "MONTEE" et "FORT" clairement articulées dans RUE DE LA MONTEE DU FORT et ne consituent ni une indication de lieu (FORT) ni de voie "MONTEE"
    De même que QUAI dans RESIDENCE DU QUAI
    et RESIDENCES DANS RUE DES RESIDENCES FLEURIES

    C'est ce à quoi me sert cette REGEX,
    mais pour désactiver une balise, faut il encore que je sache si il y a une balise auparavant, car si ce n'est pas le cas c'est que c'est bien une balise valide, comme RUE et RESIDENCE dans "6 RUE DE LA MONTEE DU FORT RESIDENCE LE RICHELIEU".
    D'où l'utilité des expressions arrières, non ?

  4. #4
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    Après quelques essais, je pense avoir trouvé la raison du problème, qui n'est cependant pas une explication.

    Les assertions arrières ne semblent pas supporter les longueurs variables.
    Je n'ai aucune idée si ça viens de l'implémentation SAS des Regex de Perl, ou si c'est dans les spécifications de Perl.

    Je suis toujours à la recherche d'une solution pour contourner le problème, car je préfère suffixer mes balises *I* éventuellement en *IN* plutot qu'en *J* ce pour des raisons de souplesse et de clareté des traitements.

    Une autre solution serait de doubler la lettre ou de la suffixer par 0 pour exprimer qu'elle n'a pas de suffixe, *V* deviendrait *VV* ou encore *V0* *I* deviendrait *II* ou *I0* .
    Et mes alternatives se feraient sous longueur fixe, par exemple avec la suffixation en 0
    [VIL][0N] à la place de [VIL] devrait pas poser de problème, je trouve ça néanmoins un peu lourd...

  5. #5
    Membre expérimenté
    Homme Profil pro
    Attaché statisticien
    Inscrit en
    Mai 2011
    Messages
    687
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Attaché statisticien
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Mai 2011
    Messages : 687
    Points : 1 581
    Points
    1 581
    Par défaut
    J'en ignore la raison, mais l'explication est ici

    Look-Ahead and Look-Behind Behavior

    "specifies a zero-width, positive, look-behind assertion. For example, in the expression (?<=regex1) regex2, a match is found if both regex1 and regex2 match. regex1 is not included in the final match. Works with fixed-width look-behind only."


    http://support.sas.com/documentation...a003288497.htm

    Je n'avais donc pas à aller loin...

    et donc pas de longueur variables dans les assertions arrières, par contre elles sont acceptées dans les assertions avant...

    Résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème avec les regex
    Par atchopba dans le forum Langage
    Réponses: 4
    Dernier message: 29/07/2013, 09h28
  2. Problème avec les regex
    Par fred33 dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 05/10/2012, 12h07
  3. problème avec les regex
    Par regisyves dans le forum ASP
    Réponses: 0
    Dernier message: 31/03/2010, 23h20
  4. REGEX problème avec les "
    Par storm_2000 dans le forum Collection et Stream
    Réponses: 9
    Dernier message: 30/11/2006, 18h32
  5. [RegEx] Problème avec les regex
    Par dragon noir dans le forum Langage
    Réponses: 3
    Dernier message: 24/07/2006, 11h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo