Blog Archive

RPGLE string manipulation - find and replace using %replace() and %scan()

%REPLACE returns the character string produced by inserting a replacement string into the source string, starting at the start position and replacing the specified number of characters.


%REPLACE(replacement string: source string{:start position {:source
length to replace}})

%SCAN returns the first position of the search argument in the source string, or 0 if it was not found. If the start position is specified, the search begins at the starting position. The result is always the position in the source string even if the starting position is specified. The starting position defaults to 1.


%SCAN(search argument : source string {: start})

Just doing a replace with a string data is fun to learn but not practical. In daily use we have to find something and then replace that with a new string data. To achieve that we need the help of two BIFs %replace() and %scan().

Simple Find and Replace

d $string_data    s             52a                          
d $scan_data      s             10a   inz('&')               
d $replace_data   s             10a   inz('&')           
d $pos            s             10i 0                        
                                                             
 /free                                                       
                                                             
   $string_data = 'Drink water & juice, Drink water & juice!';
                                                             
   $pos = %scan(%trim($scan_data):$string_data);             
   if ($pos > 0);                                            
   $string_data = %replace( %trim($replace_data)             
                           : $string_data                    
                           : $pos                            
                           : %len(%trim($scan_data)));       
   dsply $string_data;                                       
   //Drink water & juice, Drink water & juice!           
   endif;                                                                                               
   *inlr = *on;                                                      
 /end-free    

There is still an issue with the above code. The character "&" is twice in there and it will only replace the first instance. We have to modify the above code to put in a loop.

Find and Replace All

   $pos = 1;                                                        
   $string_data = 'Drink water & juice, Drink water & juice!';      
      dou $pos <= 0;                                                
                                             
        $pos = %scan(%trim($scan_data):$string_data:$pos);          
        if ($pos = 0);                                              
            leave;                                                  
        endif;                                                      
        $string_data = %replace( %trim($replace_data)               
                           : $string_data                           
                           : $pos                                   
                           : %len(%trim($scan_data)));              
        if ($pos + %len(%trim($replace_data)) > %len($string_data));
            leave;                                                  
        endif;                                                      
      enddo;                                                        
   dsply $string_data;                                              
   //Drink water &amp; juice, Drink water &amp; juice!  

This loop scans for the "&" string, and when it finds that string, it replaces that with "&amp;" and then it continues to do the same for the resulting string until there is nothing left to replace.

%REPLACE()

  • The first and second parameter must be of type character, graphic, or UCS-2 and can be in either fixed- or variable-length format. The second parameter must be the same type as the first.
  • The third parameter represents the starting position, measured in characters, for the replacement string. If it is not specified, the starting position is at the beginning of the source string. The value may range from one to the current length of the source string plus one.
  • The fourth parameter represents the number of characters in the source string to be replaced. If zero is specified, then the replacement string is inserted before the specified starting position. If the parameter is not specified, the number of characters replaced is the same as the length of the replacement string. The value must be greater than or equal to zero, and less than or equal to the current length of the source string.
  • The starting position and length may be any numeric value or numeric expression with no decimal positions.
  • The returned value is varying length if the source string or replacement string are varying length, or if the start position or source length to replace are variables. Otherwise, the result is fixed length.

%SCAN()

  • The first parameter must be of type character, graphic, or UCS-2. The second parameter must be the same type as the first parameter. The third parameter, if specified, must be numeric with zero decimal positions.
  • When any parameter is variable in length, the values of the other parameters are checked against the current length, not the maximum length.
  • The type of the return value is unsigned integer. This built-in function can be used anywhere that an unsigned integer expression is valid.

2 comments :

  1. You may want to increment the $pos position after the %replace so you do not find the & in & again on the next loop after the first replacement.

    ReplyDelete
  2. What Bob said - this will loop otherwise, building the resultant string up...

    Drink water &amp;amp;amp;.....

    ReplyDelete