SAS/Macro String Replace Function

From sasCommunity
< SAS
Jump to: navigation, search

Description

I can hardly believe there is not something like this already in SAS/Base. I asked around me, search the web, browsed the docs. unfortunately without success. These are not super solid functions, they might failed in various circumstances. but it worked for me and answer the need I had. I first needed something that would replace the first occurrence in a SAS/Macro variable. Then I modified it to loop until all occurrences are replaced. I hope this help for you, use at your own risk.

Code

%macro singlereplace(in_what, from_what, to_what);                              
    %let pos_fw = %index(&in_what, &from_what);                                 
    %if &pos_fw > 0 %then %do;                                                  
        %let l_str = %substr(&in_what, 1, %eval(&pos_fw - 1));                  
        %let r_str = %substr(&in_what, %eval(&pos_fw + %length(&from_what)));   
        &l_str&to_what&r_str                                                    
    %end; %else %do;                                                            
       &in_what                                                                 
    %end;                                                                       
%mend;                                                                          
                                                                                
%macro strreplace(in_what, from_what, to_what);                                 
    %let s=&in_what;                                                            
    %do %while(%index(&s, &from_what) > 0);                                     
        %let pos_fw = %index(&s, &from_what);                                   
        %if &pos_fw > 0 %then %do;                                              
            %let l_str = %substr(&s, 1, %eval(&pos_fw - 1));                    
            %let r_str = %substr(&s, %eval(&pos_fw + %length(&from_what)));     
            %let s=&l_str&to_what&r_str;                                        
        %end;                                                                   
    %end;                                                                       
    &s                                                                          
%mend;         

Usage


%let str1=I_WISH_THERE_WOULD_BE_NO_UNDERSCORE_IN_THIS_STRING;
%let ts=%strreplace(&string, _, );


By

User:Mathieu

Alternative Approach

Instead of creating a new macro that needs to be stored and maintained one could perform the operation with a single line of macro code.



%Let StringToModify = This_Is_The_String_To_Modify ;
%Let ModifiedString = %SysFunc( TranWrd( &StringToModify , _ , %Str( ) ) ) ;
%Put ModifiedString = &ModifiedString ;

Copyright (C) 2008 Paul OldenKamp
The above code is free software; you can redistribute it and/or modify it under the 
terms of the GNU General Public License as published by the Free Software Foundation; 
version 3 of the license.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
See the GNU General Public License for more details.

The GNU General Publice License can be obtained at http://www.gnu.org/licenses/gpl.html

Copyright (c) 2008 Paul OldenKamp
Permission is granted to copy, distribute and/or modify (the non-code portions of) this
document under the terms of the GNU Free documentation License, Version 1.1 or any later
version published by the Free Software Foundation; with no Invariant Sections; and with
no Front-Cover Texts; and with no Back-Cover Texts.

A copy of this license can be obtained at http://www.gnu.org/licenses/fdl.html

--Paul OldenKamp

By

User:SvendBang

New Version

Comment: Tranwrd cannot be used, if you have comma in the string or it is longer than 200 characters.

First have a look at the existing function:


  %Let str1=1:I_WISH_THERE_WOULD_BE_NO_UNDERSCORE_IN_THIS_STRING;
  %Put %StrReplace(&str1,_, );
1:IWISHTHEREWOULDBENOUNDERSCOREINTHISSTRING
  %Put %StrReplace(&str1,_,%str( ));
1:I WISH THERE WOULD BE NO UNDERSCORE IN THIS STRING
  %Let str2=2:Here we have quotes - "NewText" -;
  %Put %StrReplace(&str2,NewText,Monkey);
ERROR: Literal contains unmatched quote.
ERROR: The macro STRREPLACE will stop executing.
  %Let str3=%str(3:Here we have quotes - %"NewText%" -);
  %Put %StrReplace(&str3,NewText,Monkey);
ERROR: Literal contains unmatched quote.
ERROR: The macro STRREPLACE will stop executing.
  %Let str4=%Bquote(4:Here we have quotes - %"NewText%" -);
  %Put %StrReplace(&str4,NewText,Monkey);
ERROR: Literal contains unmatched quote.
ERROR: The macro STRREPLACE will stop executing.
  %Let str5=5:Here we have no quotes - NewText -;
  %Put %StrReplace(&str5,NewText,Monkey);
5:Here we have no quotes -Monkey-
  %Let str6=%Bquote(6:Here we have no quotes - NewText -);
  %Put %StrReplace(&str6,NewText,Monkey);
6:Here we have no quotes -Monkey-

It is quite clear that we have difficulties with handling of ". And blanks around To_what disappears.

A new version QStrReplace with Bquote helps:

Code:


%Macro QStrReplace(In_what,From_what,To_what);
%*
  20141003, SB: Name changed to QStrReplace. Bquote added.
                Unwanted side-effects: Input string is unquoted.
  20140921, SB: First version

  Source: http://www.sascommunity.org/wiki/SAS/Macro_String_Replace_Function
          Copyright (c) 2008 Paul Oldenkamp, GNU License
;
%Local s Pos_fw L_str R_str;
  %Let s=&In_what;
  %Do %While(%index(&s,&From_what) > 0);
    %Let Pos_fw=%index(&s,&From_what);
    %If &Pos_fw > 0 %then %do;
      %Let L_str=%Bquote(%substr(&s,1,%eval(&Pos_fw - 1)));
      %Let R_str=%Bquote(%substr(&s,%eval(&Pos_fw + %length(&From_what))));
      %Let s=%Unquote(&L_str&To_what&R_str);
      %End;
  %End;
  &s
%Mend QStrReplace;
Usage:

  %Put %QStrReplace(&str1,_,%str( ));
  %Put %QStrReplace(&str2,NewText,Monkey);
  %Put %QStrReplace(&str3,NewText,Monkey);
  %Put %QStrReplace(&str4,NewText,Monkey);
  %Put %QStrReplace(&str5,NewText,Monkey);
  %Put %QStrReplace(&str6,NewText,Monkey);

1:I WISH THERE WOULD BE NO UNDERSCORE IN THIS STRING
2:Here we have quotes - "Monkey" -
3:Here we have quotes - "Monkey" -
4:Here we have quotes - %"Monkey%" -
5:Here we have no quotes - Monkey -
6:Here we have no quotes - Monkey -