This page is a lookup for %replace: its parameters, the insert behaviour when the length is 0, the valid range for start, and how it differs from %subst and %scanrpl. For the rest of the string functions, see the RPGLE String BIFs Reference. The complete list of BIFs is in the RPGLE Built-in Functions Reference.
All examples are free-form RPGLE. Positions in a string start at 1.
Syntax
%replace(replacement : source {: start {: length {: *natural | *stdcharsize}}})
| Parameter | Meaning |
|---|---|
replacement | The text to put into source. Character, graphic or UCS-2 data, fixed or varying |
source | The string to change. Must be the same data type as replacement |
start | Where to begin in source. Valid range is 1 to the current length of source plus 1. Defaults to 1 |
length | How many characters of source to remove and replace. Valid range is 0 up to the number of characters from start to the end of source. Defaults to the length of replacement. A length of 0 inserts without removing anything |
*natural or *stdcharsize | Optional, and must be the last parameter when given. Chooses whether positions count characters or bytes for multibyte data |
%replace returns a varying-length result when either string argument is varying, when start or length is given as a variable, or when *natural mode is in effect; otherwise the result is fixed-length.
Replacing part of a string
dcl-s result varchar(20);
result = %replace('XX' : 'ABCDEF' : 3 : 2); // 'ABXXEF'
replacement does not have to be the same length as the piece it replaces. The result can grow or shrink.
result = %replace('12345' : 'ABCDEF' : 3 : 2); // 'AB12345EF', longer than the source
result = %replace('X' : 'ABCDEF' : 3 : 3); // 'ABXF', shorter than the source
Insert mode: length of 0
A length of 0 removes nothing, so replacement is inserted at start without deleting any characters of source.
dcl-s result varchar(20);
result = %replace('-' : 'ABCDEF' : 3 : 0); // 'AB-CDEF'
Appending to the end
Give start as one more than the current length of source to append replacement after the last character. This is the maximum valid value for start.
dcl-s base varchar(20) inz('Order');
dcl-s result varchar(20);
result = %replace('-2026' : base : %len(base) + 1); // 'Order-2026'
%REPLACE compared with %SUBST and %SCANRPL
| BIF | Use it to | Changes the length? |
|---|---|---|
%subst on the left of = | Overwrite characters in place, keeping the string’s length | No |
%replace | Return a new string with part replaced or text inserted | Yes, when replacement is a different length than length |
%scanrpl | Replace every occurrence of a search string, without knowing positions in advance | Yes, same rule as %replace |
%subst used as an assignment target changes characters at fixed positions and cannot change the overall length of a fixed field. %replace returns a new value and can grow or shrink the result. %scanrpl finds what to replace by content instead of by position; see the RPGLE %SCAN and %SCANRPL Reference when the position is not already known.
dcl-s a char(10) inz('ABCDEF');
%subst(a : 3 : 2) = 'XX'; // a is now 'ABXXEF ', same length
Building a string incrementally
Because %replace can both grow and shrink the result, it is a convenient way to patch one field inside a longer value without rebuilding the whole string with concatenation.
dcl-s line varchar(80) inz('Customer: [NAME], Balance: [AMT]');
dcl-s pos int(10);
pos = %scan('[NAME]' : line);
if pos > 0;
line = %replace('Anna Smith' : line : pos : 6);
endif;
Worked example: fixed-width report line
A report line sometimes needs one field patched without rebuilding the whole line. This worked example starts from a fixed-width line, finds the field to change with %scan, and patches it with %replace while keeping the overall line length the same.
dcl-s line char(40) inz('CUST 001234 STATUS PENDING ');
dcl-s pos int(10);
pos = %scan('PENDING' : line);
if pos > 0;
line = %replace('APPROVED' : line : pos : 7);
endif;
// line is now 'CUST 001234 STATUS APPROVED '
Here replacement (‘APPROVED’, 8 characters) is longer than length (7, the width of ‘PENDING’), so the result grows by one character. Assigning the result back into the fixed char(40) field truncates or pads it to 40 characters again, the same rule that applies to any assignment into a fixed-length target. If the field being patched must stay the same width regardless of the replacement text’s length, pad replacement to that width before calling %replace, or use %subst on the left of an assignment instead, which never changes the target’s length.
Multibyte data
Like the other string BIFs, %replace accepts a final optional parameter, *natural or *stdcharsize, which chooses whether start and length count characters or bytes. It only matters for multibyte data such as UTF-8, and the examples on this page use single-byte data and do not need it. For CCSID handling, read the ILE RPG String Handling tutorial.
Common mistakes
- Giving a
startbeyond%len(source) + 1, which is a run-time error rather than a no-op. - Giving a
lengththat runs past the end ofsourceinstead of stopping at it. - Expecting
%replaceto search for text. It replaces by position; use%scanto find the position first, or use%scanrplto replace by content. - Forgetting that a length of 0 inserts rather than replaces nothing; a length of 0 is not the same as calling
%replacewith no effect. - Mixing a fixed-length
replacementwith a fixed-lengthsourceand expecting the overall variable to grow; the result is only longer when the field receiving it is varying or large enough.
FAQ
How do I insert text into the middle of a string with %REPLACE?
Give length as 0. %replace(text : source : start : 0) inserts text at start without removing anything.
What happens if the replacement text is a different length than the part it replaces?
The result changes length. %replace returns a string that is shorter or longer than source, unlike %subst used as an assignment target, which never changes a fixed field’s length.
What is the difference between %REPLACE and %SCANRPL?
%replace changes a known position and length. %scanrpl finds and replaces every occurrence of a search string by content, without you supplying a position.
Related BIFs
- RPGLE String BIFs Reference: the full string family, including
%subst,%trimand%len. - RPGLE %SCAN and %SCANRPL Reference: finding a position and replacing every occurrence.
- RPGLE Built-in Functions Reference: the full index by task.
Summary
%replace(replacement : source : start : length)returns a new string with part ofsourcereplaced; alengthof 0 inserts instead.startruns from 1 to%len(source) + 1; going past either end is a run-time error.- Unlike
%substused as an assignment target,%replacecan change the result’s length.