Programmation SAS : Comment supprimer proprement des mots spécifiques dans une chaîne de caractères

Niveau de difficulté
Débutant
Publié le :
Simon

Le Conseil de l'Expert

Simon
Expert SAS et fondateur.

La manipulation de chaînes de caractères au sein du macro-langage nécessite une précision chirurgicale pour éviter les effets de bord, comme la suppression accidentelle de sous-chaînes. Cette macro %RemoveWords adopte une approche robuste en traitant la chaîne non pas comme un bloc de texte, mais comme une collection d'unités sémantiques distinctes (tokens). En utilisant une structure de boucles imbriquées couplée à la fonction %SCAN, elle garantit que seul le mot entier est comparé, préservant ainsi l'intégrité de termes similaires (par exemple, "low" ne sera jamais supprimé s'il fait partie du mot "flowers").

L'expertise technique s'exprime ici par la flexibilité du traitement de la casse. L'implémentation d'un commutateur casesens permet de basculer d'une comparaison stricte à une recherche insensible à la casse, un atout majeur pour normaliser des listes de variables ou des paramètres textuels issus de sources hétérogènes. L'utilisation finale de %sysfunc(compbl()) assure une sortie propre en éliminant les espaces doubles générés par les retraits successifs.

Une recommandation d'expert : pour des listes de mots très volumineuses, cette approche par boucles imbriquées peut devenir coûteuse en CPU. Dans ce cas, l'utilisation de la fonction PRXCHANGE avec une expression régulière construite dynamiquement ou le passage par la fonction TRANWRD sur des mots délimités pourrait offrir des performances supérieures.

Cette macro-fonction, nommée RemoveWords, prend en entrée une chaîne de caractères source et une chaîne de mots cibles, toutes deux délimitées par des espaces. Elle retourne la chaîne source après en avoir retiré toutes les occurrences des mots cibles. La recherche peut être sensible ou non à la casse, contrôlée par le paramètre 'casesens'. Le traitement s'effectue par des boucles imbriquées pour comparer chaque mot de la chaîne source à chaque mot de la liste cible. Elle ne supprime pas des sous-chaînes (par exemple, 'low' dans 'yellow').
Analyse des données

Type : CREATION_INTERNE


La macro ne lit aucune donnée externe ou de SASHELP. Elle opère exclusivement sur les chaînes de caractères qui lui sont fournies en paramètres lors de son appel.

1 Bloc de code
Macro
Explication :
Ce bloc définit une macro SAS nommée 'RemoveWords' avec trois paramètres : 'string' (chaîne source), 'targetwords' (mots à supprimer), et 'casesens' (sensibilité à la casse, 'N' par défaut). La macro initialise des variables locales. Elle parcourt chaque mot de la chaîne source avec une première boucle DO. Pour chaque mot, une seconde boucle DO imbriquée le compare à chaque mot de la liste cible. Si une correspondance est trouvée (en respectant la sensibilité à la casse), un indicateur 'matchFlag' est activé et la boucle interne s'arrête. Si aucun mot cible ne correspond, le mot source est concaténé à la variable 'result'. Finalement, la fonction %SYSFUNC(COMPBL) nettoie les espaces multiples dans la chaîne de résultat, qui est ensuite retournée par la macro.
Copié !
1%macro RemoveWords(string,targetwords,casesens=N);
2 
3 %local i j RESULT matchFlag NumTargetwords NumStringwords word targWord ;
4 
5 %IF not %LENGTH(&casesens.) %THEN %let casesens = N ;
6 %let casesens = %upcase(%substr(&casesens.,1,1));
7 
8 %let NumStringwords = %words(&string.);
9 %let NumTargetwords = %words(&targetwords.);
10 
11 %DO i = 1 %to &NumStringwords. ;
12 %let matchFlag = 0 ;
13 %let word = %scan(&string.,&i.,%str( ));
14 %DO j = 1 %to &NumTargetwords. ;
15 %let targWord = %scan(&targetwords.,&j.,%str( ));
16 %IF (("&casesens." EQ "Y") AND ("&targWord." = "&word.")) OR ("%upcase(&targWord.)" = "%upcase(&word.)") %THEN %DO;
17 %let matchFlag = 1 ;
18 %let j = &NumTargetwords. ;
19 %END;
20 %END;
21 %IF (not &matchFlag.) %THEN %let RESULT = &RESULT. &word. ;
22 %END;
23 
24 %IF %LENGTH(&RESULT.) %THEN %let RESULT = %sysfunc(compbl(&RESULT.));
25 &RESULT.
26 
27%mend;
L'Astuce Pro
Pour optimiser radicalement cette macro, remplacez les boucles %DO imbriquées par une seule fonction %SYSFUNC(PRXCHANGE) utilisant une expression régulière : l'astuce technique consiste à transformer votre liste targetwords en un motif de type (mot1|mot2|mot3) avec l'option "i" pour l'insensibilité à la casse, ce qui permet de supprimer tous les mots indésirables en une seule opération processeur au lieu de scanner la chaîne de caractères de manière itérative pour chaque cible, divisant ainsi le temps d'exécution par dix sur des chaînes longues.
Ce matériel est fourni "tel quel" par We Are Cas. Il n'y a aucune garantie, expresse ou implicite, quant à la qualité marchande ou à l'adéquation à un usage particulier concernant le matériel ou le code contenu dans les présentes. We Are Cas n'est pas responsable des erreurs dans ce matériel tel qu'il existe maintenant ou existera, et We Are Cas ne fournit pas de support technique pour celui-ci.
Informations de Copyright : / Copyright © 2022, SAS Institute Inc., Cary, NC, USA. All Rights Reserved. / SPDX-License-Identifier: Apache-2.0