• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Guru Classic: A Bevy of BIFs, %XLATE and %REPLACE

    March 6, 2019 Jon Paris

    Author’s Note: I’m revisiting this classic tip since the original was written back in 2009, long before the introduction of free-form data declarations. In addition, I’ve updated this tip to point to the new %SCANRPL BIF, which impacts this scenario. And, of course, I still regularly encounter RPGers who are confused by the differences between the %XLATE and %REPLACE built-in functions (BIFs). Part of that confusion of course is the result of wishful thinking on the part of those frustrated by the limitations of %XLATE!

    The first thing to remember when deciding which function to use is that %XLATE operates on individual characters and %REPLACE operates on strings. In this regard they are similar to the %SCAN and %CHECK BIFs that I discussed in this tip.

    This story contains code, which you can download here.

    Before we study %REPLACE, let’s quickly review the function of %XLATE.

    %XLATE( from : to : input {: startpos} )
    

    The function of %XLATE is to search the input string for any instances of the individual characters contained in the from string and to replace them with the corresponding character in the to string. So in this example:

    result = %XLATE( 'ABC': 'XYZ': source);
    

    Any occurrences of the character ‘A’ in the source string will be replaced by ‘X’, ‘B’ by ‘Y’, and ‘C’ by ‘Z’. So if we assume that source contains ‘123ABC789’ before the operation, afterward the result will contain ‘123XYZ789’.

    The mistake that some programmers make is to think that %XLATE is replacing the combination of characters. In other words, in the above example, the string ‘ABC’ is being replaced. It is, but only as the result of the characters ‘A’, ‘B’, and ‘C’ being individually replaced. Had the input contained ‘ABD’, it would have been converted to ‘XYD’. This misconception can result in code being written that will “almost” work and that may under test conditions appear to work correctly.

    Suppose that we want to replace any occurrence of the character string ‘/*’ with ‘&&’. The programmer might code:

    result = %Xlate( '/*':  '&&': source);
    

    But while this may appear at first glance to work, it will not only convert all instances of ‘/*’ but, because it is operating on a character by character basis, it will also translate individual ‘/’ or ‘*’ characters – probably not what was wanted. The following code demonstrates this effect:

        Dcl-S  from  varchar(5)  Inz('/*');
        Dcl-S  to    varchar(5)  Inz('&&');
    
        source = '123ABC789';
        result = %XLATE( 'ABC': 'XYZ': source);
    
        dsply ('Source: ' + source);
        dsply ('Result: ' + result);
    
        dsply ('Convert /* to && the wrong way with %Xlate');
    
        source = '/* Leave /these/ and *these* /*';
        result = %Xlate(from: to: source);
        // - Result contains '&& Leave &these& and &these& &&'
    
        dsply ('Source: ' + source);
        dsply ('%XLate from ' + from + ' to ' + to );
        dsply ('Result is: ' + result);
    
    

    At the time the original version of this tip was published, it actually required a combination of the %SCAN and %REPLACE BIFs to achieve this task. Since that time however, RPG has added the built-in function %SCANRPL and this operates as desired in this example (i.e., to replace every occurrence of one string with another). But suppose you only wanted to replace the first (or last or third) occurrence of the string. In that case, you would still need to use the scan/replace combination. So I am still covering the example of using the combination here. In addition I have included an example of the %SCANRPL equivalent in the associated source file as well. If you want the full details of %SCANRPL you can find them in this article: A Bevy Of BIFs: %ScanRpl (Scan And Replace)

    %REPLACE

    The basic syntax for %REPLACE is:

    %REPLACE( replacement : source { :startpos {: length to replace}} )
    

    The code below demonstrates how the %SCAN and %REPLACE BIFs can be used in combination to achieve the desired functionality. The start position for the string to be replaced is obtained by an initial %SCAN (A). It is then used to specify the start position for the %REPLACE operation (B). On the subsequent scan operations, the optional start parameter (C) is used to skip past the portion of the string that has already been processed.

        Dcl-S  from    Varchar(5)  Inz('/*');
        Dcl-S  to      Varchar(5)  Inz('&&');
    
        Dcl-S  position  Int(5);
        Dcl-S  start     Int(5);
    
        Dcl-S  custName  varchar(12);
    
        Dcl-S  marker    varchar(10);
    
       // This is a valid approach to handling character strings
       //  - It will result in '&& Leave /these/ and *these* &&'
    
       dsply ('Convert /* to && the "right" way with %Scan/%Replace');
    
        result = '/* Leave /these/ and *these* /*';
    
    (A) position = %Scan( from: result);
    
        DoW position > 0;
          // If replacing all occurrences %SCANRPL works better
          // But logic could be added here to check for which
          //  occurrence(s) should be replaced
    (B)   result = %Replace( to: result: position);
          start = position + 1;
    (C)   position = %Scan( from: result: start);
        EndDo;
    
        dsply ('Source: ' + source);
        dsply ('%Replace ' + from + ' With ' + to );
        dsply ('Result is: ' + result);
    

    Although less useful than it was before the advent of %SCANRPL, %REPLACE does have a number of nice features. For one, the length of the replacement string does not have to match the length of the text to be replaced. In such cases, the optional fourth parameter is used to specify the number of characters to be replaced. This makes the BIF very useful in mail-merge type operations where you want to replace a text marker with a variable amount of text. For example, the base text might include a marker like “&Name”, which we are going to replace with the customer’s name. So we might code the %REPLACE operation like this:

    marker = '&Name';
    position = %Scan(marker: source);
    result = %Replace( custName: source: position: %Len(marker));
    

    This will cause the BIF to replace “&Name” (five characters) with the content of custName. The above code assumes that custName is a variable length field; if it were not we would have had to code %TrimR(custName) as the parameter to avoid inserting potentially large numbers of blanks.

    There is a lot more we could say about %REPLACE, but the intent of this tip is to clarify the differences between %XLATE and %REPLACE. Plus, as I noted earlier, %SCANRPL has replaced the use of %REPLACE in many cases.

    If there are any other BIFs you’d like me to cover in future tips please let me know via the comments.

    Jon Paris is one of the world’s foremost experts on programming on the IBM i platform. A frequent author, forum contributor, and speaker at User Groups and technical conferences around the world, he is also an IBM Champion and a partner at Partner400 and System i Developer. He hosts the RPG & DB2 Summit twice per year with partners Susan Gantner and Paul Tuohy.

    RELATED STORIES

    A Bevy Of BIFs: %ScanRpl (Scan And Replace)

    A Bevy of BIFs – %SCAN and %CHECK

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags: Tags: 400guruclassic, BIF, FHGC, Four Hundred Guru Classic, IBM i, RPG

    Sponsored by
    Raz-Lee Security

    With COVID-19 wreaking havoc, cybercriminals are taking advantage of the global impact that it has had on our families, our businesses and our societies. It is more important now than ever to ensure that IT systems are protected, so that when all of this is behind us, we can get back to business as usual as quickly as possible.

    iSecurity Anti-Ransomware protects organizations against ransomware attacks and other kinds of malware that may access and change business-critical data on your IBM i. It even protects against zero-day attacks. Anti-Viruses can only report on the damage an attack has caused, but not stop it.

    iSecurity Anti-Ransomware has been recently enhanced with a Self-Test feature that allows you to simulate a ransomware attack on your IBM i. The simulated attack is limited to the test folder and cannot harm any other folders or files. This new feature lets organizations see how they are protected against known or unknown ransomware.

    Key Features:

    • Real-time scanning for known and unknown ransomware threats.
    • Blocks and disconnects the intruder.
    • Instantaneously sends alerts to SIEM as well as the offending computer.
    • Self-Test for attack simulation
    • Classification of the attack based on log.
    • Automatic updates with the most current ransomware definitions.

    Contact us at https://www.razlee.com/anti-ransomware

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    The Problem With ERP Guru Classic: Custom Perspectives In RDi, Part 2

    Leave a Reply Cancel reply

TFH Volume: 29 Issue: 14

This Issue Sponsored By

  • RPG & DB2 Summit
  • RPG & DB2 Summit
  • RPG & DB2 Summit

Table of Contents

  • Guru Classic: What’s That Name, Again?
  • Guru Classic: Custom Perspectives In RDi, Part 2
  • Guru Classic: A Bevy of BIFs, %XLATE and %REPLACE

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • IBM Extends Dynamic Capacity Pricing Scheme To Its Cloud
  • Here’s What You Should Do About The IBM i Skills Shortage
  • Matillion Founder Recounts Midrange Roots
  • Four Hundred Monitor, February 24
  • IBM i PTF Guide, Volume 23, Number 8
  • iTech Solutions Keeps You In The Know With VERIFi
  • Tech Data’s Take On Certified Pre-Owned IT Gear
  • Guru: Prompting Stored Procedures
  • As I See It: Sunshine Or Oxygen?
  • Looking For Some Insight On IBM i Security

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2021 IT Jungle

loading Cancel
Post was not sent - check your email addresses!
Email check failed, please try again
Sorry, your blog cannot share posts by email.