%SCANRPL
Remplacer toutes les occurrences d'un texte
Renvoie la chaîne dans laquelle toutes les occurrences d'un texte sont remplacées par un autre, de longueur différente si besoin.
Syntaxe
%SCANRPL(recherché : remplaçant : chaîne)
%SCANRPL(recherché : remplaçant : chaîne : début)
%SCANRPL(recherché : remplaçant : chaîne : début : longueur)
recherché- Le texte à remplacer. Il ne peut pas être vide : le compilateur le refuse (RNF0665).
remplaçant- Le texte mis à la place. Il peut être vide (
'') pour supprimer les occurrences, et sa longueur peut différer de celle du texte recherché. chaîne- La chaîne à traiter. Elle n'est pas modifiée : la fonction renvoie un nouveau texte.
début- Position à partir de laquelle on remplace (par défaut 1).
longueur- Longueur de la zone traitée à partir de
début. Ce qui est hors de la zone reste tel quel. - Résultat
- Une chaîne variable, de longueur éventuellement différente de la chaîne d'origine. La recherche respecte la casse.
À quoi ça sert
Remplacer toutes les occurrences demandait une boucle avec %SCAN et %REPLACE, en surveillant les positions qui se décalent. %SCANRPL fait tout en un appel : changer un séparateur CSV, supprimer un mot, normaliser une raison sociale.
Exemple 1 : Remplacer, supprimer, limiter la zone
**free
// %SCANRPL : remplacer toutes les occurrences d'un texte.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s phrase varchar(80) inz('Dupont SA - Dupont SA Lyon - dupont SA');
dcl-s csv varchar(40) inz('100;Martin et fils;Lyon');
snd-msg 'Original : [' + phrase + ']';
snd-msg 'SA -> SARL : [' + %scanrpl('SA' : 'SARL' : phrase) + ']';
snd-msg 'Dupont -> D.: [' + %scanrpl('Dupont' : 'D.' : phrase) + ']';
// Un texte de remplacement vide supprime les occurrences.
snd-msg 'Sans " SA" : [' + %scanrpl(' SA' : '' : phrase) + ']';
snd-msg 'CSV -> | : [' + %scanrpl(';' : ' | ' : csv) + ']';
// Limiter la zone traitee : 4e param = debut, 5e = longueur.
snd-msg 'Debut 10, 15: [' + %scanrpl('SA' : 'XX' : phrase : 10 : 15) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Original : [Dupont SA - Dupont SA Lyon - dupont SA]
SA -> SARL : [Dupont SARL - Dupont SARL Lyon - dupont SARL]
Dupont -> D.: [D. SA - D. SA Lyon - dupont SA]
Sans " SA" : [Dupont - Dupont Lyon - dupont]
CSV -> | : [100 | Martin et fils | Lyon]
Debut 10, 15: [Dupont SA - Dupont XX Lyon - dupont SA]
SA devient SARL partout. La casse compte : en cherchant Dupont, le dupont en minuscules reste intact. Avec un remplaçant vide, les occurrences disparaissent. Avec un début et une longueur (10 et 15), seul le SA situé dans cette zone est remplacé.
Exemple 2 : Tronquage silencieux et chevauchements
**free
// %SCANRPL : le resultat est tronque sans erreur si la zone receptrice est trop courte.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s nom char(14) inz('Dupont SA Lyon');
dcl-s court char(12);
dcl-s long varchar(40);
court = %scanrpl('SA' : 'SOCIETE ANONYME' : nom);
long = %scanrpl('SA' : 'SOCIETE ANONYME' : nom);
snd-msg 'Zone de 12 : [' + court + ']';
snd-msg 'Zone de 40 : [' + long + ']';
snd-msg 'Longueur : ' + %char(%len(long));
// Les occurrences qui se chevauchent : lecture de gauche a droite, sans recouvrement.
snd-msg 'aaaa : [' + %scanrpl('aa' : 'b' : 'aaaa') + ']';
snd-msg 'aaa : [' + %scanrpl('aa' : 'b' : 'aaa') + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Zone de 12 : [Dupont SOCIE]
Zone de 40 : [Dupont SOCIETE ANONYME Lyon]
Longueur : 27
aaaa : [bb]
aaa : [ba]
Le résultat fait 27 caractères. Rangé dans une zone fixe de 12, il est coupé en Dupont SOCIE, sans aucune erreur ni avertissement. Dans une variable de 40, il tient en entier.
Deux occurrences qui se chevauchent ne sont pas comptées deux fois : aa dans aaa est remplacé une fois (on lit de gauche à droite), il reste le dernier a.
Le piège
Le résultat peut être plus long que la zone d'arrivée, et il est alors coupé sans erreur. Remplacer SA par SOCIETE ANONYME allonge le texte à chaque occurrence ; rangé dans une zone trop courte, il est simplement tronqué (Dupont SOCIE). Prévoir une zone assez grande, ou comparer %LEN du résultat avec la taille de la zone.
Autres points : la casse compte, et un texte recherché vide est refusé à la compilation.