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 :

Expression régulière pour un prxchange récalcitrant


Sujet :

SAS Base

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Lot (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2016
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Expression régulière pour un prxchange récalcitrant
    Bonjour,

    Dans le cadre d'une procédure d'automatisation de data cleansing, je cherche à supprimé tous les accents d'une variable texte : txt_incident . Je souhaite utilisé la fonction prxchange mais je suis novice en langage pearl et je n'arrive pas à construire l'expression régulière dont j'ai besoin

    en gros, j'ai une première table ("TABLETEXTMINING1") récapitulant les caractères à remplacer et leur caractère de remplacement:
    unit HEX Base Fin regex regex2
    1 81 ü u s/x81/u/ s/ü/u/
    2 82 é e s/x82/e/ s/é/e/
    1 83 â a s/x83/a/ s/â/a/
    2 84 ä a s/x84/a/ s/ä/a/
    1 85 à a s/x85/a/ s/à/a/
    2 86 å a s/x86/a/ s/å/a/
    1 87 ç c s/x87/c/ s/ç/c/
    2 88 ê e s/x88/e/ s/ê/e/
    1 89 ë e s/x89/e/ s/ë/e/
    2 8A è e s/x8A/e/ s/è/e/
    1 8B ï i s/x8B/i/ s/ï/i/
    2 8C î i s/x8C/i/ s/î/i/
    1 8D ì i s/x8D/i/ s/ì/i/
    2 91 æ ae s/x91/ae/ s/æ/ae/
    1 94 ö o s/x94/o/ s/ö/o/
    2 95 ò o s/x95/o/ s/ò/o/
    1 96 û u s/x96/u/ s/û/u/
    2 97 ù u s/x97/u/ s/ù/u/
    1 98 ÿ y s/x98/y/ s/ÿ/y/
    2 A0 á a s/xA0/a/ s/á/a/
    1 A1 í i s/xA1/i/ s/í/i/
    2 A2 ó o s/xA2/o/ s/ó/o/

    et l'idée c'est que pour chaque observation de txt_incident tous les caractères listé dans la table TABLETEXTMINING1.base soit remplacé par leur caractère respectif dans TABLETEXTMINING1.fin
    malheuresement la solution suivante ne marche pas...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    PROC SQL;
       CREATE TABLE blabla.QUERY_FOR_TABLETEXTMINING1_0000 AS 
       SELECT t1.NUMINCIDENT, 
              t1.DATINCIDENT_DETECT, 
              t1.txt_incident, 
              t1.inf comp incident, 
              /* txt_incident_sans_accent */
                (PRXCHANGE(t2.regex2,-1, t1.txt_incident)) AS txt_incident_sans_accent 
          FROM blabla.CTRL_E_JUSTIFICATION_BASE t1, blabla.TABLETEXTMINING1 t2;
    QUIT;

  2. #2
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Bonjour Sophie.
    Dans le programme que tu présentes, la requête SQL va créer un produit cartésien entre les deux tables. En gros, pour chaque ligne de ton fichier TABLETEXTMINING1 il y aura 22 observations créées (puisque tu as 22 caractères spéciaux à remplacer dans la liste que tu postes), chacune avec un type de caractère remplacé seulement. Par exemple, dans 1 de ces 22 duplications, les é seront remplacés par des e. Et à la ligne d'après, les è par des e. Etc.
    Je ne pense pas que ce soit exactement ce que tu veux.
    Le remplacement caractère par caractère peut être géré par la fonction TRANSLATE sans passer par une expression régulière. TRANSLATE(varTexte,"aee","àéè") va remplacer chacun des caractères accentués du 3e argument par son homologue sans accent -- attention à leur ordre qui doit être identique dans le 2e argument.
    Pour utiliser la table que tu as déjà créé, on peut passer par des macro-variables pour générer le 2e et le 3e argument de ta fonction TRANSLATE.
    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
    PROC SQL NOPRINT ;
      SELECT base, fin
        INTO : liste_base SEPARATED BY "",
             : liste_fin SEPARATED BY ""
      FROM blabla.CTRL_E_JUSTIFICATION_BASE ;
    QUIT ;
    PROC SQL ;
       CREATE TABLE blabla.QUERY_FOR_TABLETEXTMINING1_0000 AS 
       SELECT t1.NUMINCIDENT, 
              t1.DATINCIDENT_DETECT, 
              t1.txt_incident, 
              t1.inf comp incident, 
              /* txt_incident_sans_accent */
                TRANSLATE(t1.txt_incident,"&liste_fin","&liste_base") AS txt_incident_sans_accent 
          FROM blabla.CTRL_E_JUSTIFICATION_BASE t1 ;
    QUIT ;
    Bon courage.
    Olivier
    Bon courage.
    Olivier

  3. #3
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2016
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 32
    Localisation : France, Lot (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2016
    Messages : 2
    Points : 1
    Points
    1
    Par défaut Merci et question
    Bonjour,

    Merci infiniment pour ce code qui marche très bien, la fonction translate est effectivement la solution transitoire pour laquelle j'ai opté. Seulement voilà, dans le cadre de ce projet je fais essentiellement du text mining à partir de tables externes contenant des mots clés pour chaque variable sur le même modèle que ma première demande (j'aurais également recours aux autres fonctions utilisant les expressions régulières type prxmatch etc..) j'ai vraiment besoin de comprendre comment créer une expression régulière comprenant l'appel de macro variable type :


    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
     
    data _null_;
    set blabla.TABLETEXTMINING1;
    call symput("derniereligne", _n_);
    run;
    %put &derniereligne.;
    %macro hope;
     
    %do i=1 %to &derniereligne;
    %let a = TABLETEXTMINING1.regex.&i;
    PROC SQL;
    		CREATE TABLE bd3 AS
    		SELECT numincident , DATINCIDENT_DETECT, txt_incident FROM blabla.CTRL_E_justification_BASE 
    		where txt_incident=prxchange (a,-1,txt_incident);                                                                                                                                                                                                                                                                                                                              
    QUIT;
    %end;
    %mend;
    le code ne marche il ne comprend pas l'appel de la ligne i de la colonne regex (qui est une colonne construite par concaténation de base est fin pour un rendu de type : 's/é/e/' sachant qu'une expression du type prxchange ('s/&base/&fin/',...) me convient tout à fait aussi mais dans les deux cas même problème je n'arrive pas à faire un code qui marche (toujours même problème il ne comprend pas la référence de la macro variable est par conséquent me renvoi une syntax error sur l'argument 1 de prx change)


    ou à défaut si cela est possible j'aimerai comprendre comment construire que expression régulière qui listerai touts les remplacements dans une même fonction prxchange genre : prxchange ('(s/é/e/'&s/à/a/)....',...) car malheureusement contrairement à la fonction translate prxchange comprend s/éèà/eea/ par block et donc évidement ne fait rien car ne trouve pas de chaine éèà.

    J'espère que j'ai étais claire...

    Merci encore pour toute l'aide que l'on trouve sur ce forum et bonne journée

  4. #4
    Expert confirmé
    Avatar de olivier.decourt
    Homme Profil pro
    Formateur R/SAS/statistiques
    Inscrit en
    Avril 2008
    Messages
    2 064
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Activité : Formateur R/SAS/statistiques
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 064
    Points : 4 478
    Points
    4 478
    Par défaut
    Bonjour Sophie.
    J'ai peur qu'en SQL ça soit compliqué à faire fonctionner. La boucle macro que tu essayes d'utiliser n'est jamais qu'un vaste copier/coller qui va te produire 22 requêtes SQL, chacune effectuant la correction d'un caractères et écrivant le résultat dans la même table, BD3. Au final, en sortant de la boucle, BD3 ne contiendra que la dernière correction, pas le cumul de toutes les corrections puisqu'à chaque fois tu repars du texte non corrigé.
    On pourrait garder l'idée du produit cartésien (chaque ligne de texte doit bien être confrontée aux 22 corrections) mais dans une étape Data, où on maîtrise mieux le timing d'exécution. L'idée est de faire un SET classique de ta grosse table de texte, et à chaque observation lue, une boucle sur la table des corrections avec un SET POINT (on lit directement l'observation indiquée par l'option POINT). Là, comme on réutilisera toujours la même variable en entrée et en sortie de PRXCHANGE, on peut accumuler les corrections.
    Ci-dessous un exemple.

    PS : il manque le ô dans ta base de caractères accentués à éliminer.
    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
    DATA work.textes ;
      LENGTH txt $ 100 ;
      txt = "même les mômes savent ça !" ; OUTPUT ;
      txt = "j'enseigne le théâtre à des élèves doués" ; OUTPUT ;
      txt = "ces huîtres sont inouïes" ; OUTPUT ;
    RUN ;
    DATA work.corrections ;
      INPUT unit $ HEX $ Base $ Fin $ regex $ regex2 $ ;
    DATALINES ;
    1 81 ü u s/x81/u/ s/ü/u/
    2 82 é e s/x82/e/ s/é/e/
    1 83 â a s/x83/a/ s/â/a/
    2 84 ä a s/x84/a/ s/ä/a/
    1 85 à a s/x85/a/ s/à/a/
    2 86 å a s/x86/a/ s/å/a/
    1 87 ç c s/x87/c/ s/ç/c/
    2 88 ê e s/x88/e/ s/ê/e/
    1 89 ë e s/x89/e/ s/ë/e/
    2 8A è e s/x8A/e/ s/è/e/
    1 8B ï i s/x8B/i/ s/ï/i/
    2 8C î i s/x8C/i/ s/î/i/
    1 8D ì i s/x8D/i/ s/ì/i/
    2 91 æ ae s/x91/ae/ s/æ/ae/
    1 94 ö o s/x94/o/ s/ö/o/
    2 95 ò o s/x95/o/ s/ò/o/
    1 96 û u s/x96/u/ s/û/u/
    2 97 ù u s/x97/u/ s/ù/u/
    1 98 ÿ y s/x98/y/ s/ÿ/y/
    2 A0 á a s/xA0/a/ s/á/a/
    1 A1 í i s/xA1/i/ s/í/i/
    2 A2 ó o s/xA2/o/ s/ó/o/
    ;
    RUN ;
    DATA work.textes2 ;
      SET work.textes ;
      txt2 = txt ;
      DO p=1 TO nCorr ;
        SET work.corrections POINT=p NOBS=nCorr ;
    	txt2 = PRXCHANGE(regEx2, -1, txt2) ;
      END ;
      OUTPUT ;
      KEEP txt txt2 ;
    RUN ;
    Bon courage.
    Olivier

Discussions similaires

  1. [RegEx] Expression régulière pour supprimer des doublons
    Par cbroissa dans le forum Langage
    Réponses: 5
    Dernier message: 20/05/2017, 01h59
  2. [RegEx] Expression régulière pour trouver des mots
    Par cbroissa dans le forum Langage
    Réponses: 7
    Dernier message: 26/05/2006, 23h39
  3. [RegEx] Simple expression régulière pour ereg_replace
    Par aurapp dans le forum Langage
    Réponses: 6
    Dernier message: 12/03/2006, 12h34
  4. Expression régulière pour récupérer le nom d'un fichier
    Par calimero2611 dans le forum Langage
    Réponses: 5
    Dernier message: 24/02/2006, 19h00
  5. Expression Régulière pour float
    Par zebiloute dans le forum Langage
    Réponses: 5
    Dernier message: 26/09/2005, 14h03

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