RPGLE String BIFs Reference

This page is a lookup for the RPGLE string built-in functions: what each one takes, what it returns, and the edge cases that cause run-time errors or surprising results. For worked patterns such as parsing, building messages and CCSID handling, read ILE RPG String Handling. 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.

String BIFs at a glance

BIFWhat it doesReturns
%substPart of a stringA string of the same kind as the source
%scanPosition of one string inside anotherInteger; 0 when not found
%scanrplReplace every occurrence of one string with anotherA string
%trim, %triml, %trimrRemove blanks or listed charactersA varying-length string
%replaceReplace part of a string, or insertA string
%lenLength of a valueInteger
%charConvert a number, date, time, timestamp or other string to textA character string
%check, %checkrFirst character not on an allowed listInteger; 0 when all are allowed
%xlateTranslate characters one-for-oneA string

%SUBST

Returns part of a string. The left-side assignment form and the range rules have their own page, the RPGLE %SUBST Reference.

%subst(string : start {: length})
ParameterMeaning
stringThe source value
startFirst position to return, starting at 1
lengthNumber of characters to return. If omitted, the result runs to the end of the string
dcl-s name char(20) inz('  Smith, Anna');
dcl-s surname varchar(20);

surname = %subst(%trim(name) : 1 : 5);   // 'Smith'

%SCAN

Returns the position of the first occurrence of one string inside another, or 0 when it is not found. To find every match, or to replace every occurrence with %scanrpl, see the RPGLE %SCAN and %SCANRPL Reference.

%scan(search : source {: start {: length}})

The search argument comes first and the string being searched second. This is the reverse of the order many other languages use. The optional start is the first position to search from, and the optional length limits how many characters are searched. The search is case-sensitive.

dcl-s pos int(10);

pos = %scan(',' : 'Smith, Anna');          // 6
pos = %scan('x' : 'abc');                  // 0
pos = %scan('a' : 'banana' : 3);           // 4, searching from position 3

%TRIM, %TRIML and %TRIMR

%trim removes blanks from both ends of a string. %triml removes leading blanks only, and %trimr removes trailing blanks only.

%trim(string {: characters})

With the optional second parameter, the function removes the characters you list instead of blanks.

dcl-s cleaned varchar(20);

cleaned = %trim('  ABC  ');                 // 'ABC'
cleaned = %trim('**ABC**' : '*');          // 'ABC'

The function returns a new value. It does not change the variable you pass.

%REPLACE

Replaces part of a string, or inserts text.

%replace(replacement : source {: start {: length}})
ParameterMeaning
replacementThe text to put in
sourceThe string to change
startWhere to begin. Defaults to 1
lengthHow many characters of source to replace. Defaults to the length of replacement
dcl-s result varchar(20);

result = %replace('XX' : 'ABCDEF' : 3 : 2);   // 'ABXXEF'
result = %replace('-'  : 'ABCDEF' : 3 : 0);   // 'AB-CDEF', length 0 inserts

%replace is the BIF to use for an insert. To add text at the end, give start as one more than the length of the source.

%LEN

Returns the length of a value.

%len(expression)

For a varying-length field, %len is the current length, and %len(field : *max) is its declared maximum. For a fixed-length field, it is the declared length, whatever the field holds. For alphanumeric data the length is in bytes.

dcl-s fixedTxt char(10)    inz('Hi');
dcl-s varTxt   varchar(10) inz('Hi');

// %len(fixedTxt)        is 10
// %len(varTxt)          is 2
// %len(%trim(fixedTxt)) is 2

%CHAR

Converts a value to character data.

%char(expression {: format | ccsid})

A number converts to character data without leading zeros, with a minus sign when it is negative. The decimal positions of the field are kept. For a date, time or timestamp, the second parameter is a format. For character, graphic or UCS-2 data, the second parameter is a CCSID.

dcl-s text varchar(30);
dcl-s count int(10) inz(42);

text = 'Orders: ' + %char(count);     // 'Orders: 42'

For a date, time or timestamp, the second parameter chooses the output format. Without it, the result uses the format the field was declared with.

dcl-s due date(*iso) inz(d'2026-10-05');
dcl-s shown varchar(10);

shown = %char(due : *usa);                 // '10/05/2026'

%CHECK and %CHECKR

Return the position of the first character in a string that is not in a list of allowed characters, or 0 when every character is allowed. %check scans from the left. %checkr scans from the right.

%check(comparator : base {: start})
dcl-s bad int(10);

bad = %check('0123456789' : '12a4');    // 3, the 'a'
bad = %check('0123456789' : '1234');    // 0, all digits

%XLATE

Translates characters in a string, using one list of characters to find and a parallel list to substitute.

%xlate(from : to : string {: start})
dcl-s result varchar(20);

result = %xlate('abc' : 'ABC' : 'a cat');    // 'A CAt'

Each character found in the from list is replaced by the character in the same position in the to list. Characters not in the from list are left alone.

Multibyte data

In the IBM i 7.5 reference, %subst, %scan, %replace, %check and %xlate also accept a final optional parameter, *natural or *stdcharsize. It chooses whether positions and lengths count characters or bytes, and it only matters for multibyte data such as UTF-8. The examples on this page use single-byte data and do not need it. For CCSID handling, read the ILE RPG String Handling tutorial.

Opcode to BIF mapping

Older fixed-format code uses opcodes for the same jobs. They still compile; use the BIF in new code. The full list is in the RPGLE Opcode Reference.

Fixed-format opcodeFree-form equivalent
SUBST%subst
SCAN%scan
CATthe + operator, usually with %trim
CHECK%check
XLATE%xlate

Common mistakes

  • Swapping the arguments of %scan. The thing you look for is the first argument.
  • Using the result of %scan without testing for 0.
  • Concatenating a fixed-length field without %trim, which leaves its padding blanks in the result.
  • Expecting %trim to change the variable. Assign the result to a variable.
  • Passing a start and length to %subst that run past the end of the string.
  • Calling %subst with a start or length beyond the current length, for example on the result of %trim of a field that may be blank. Test %len first.

FAQ

Why does %SCAN return 0?

The search string was not found, or the start position is past the last possible match. Zero is the normal “not found” result and is not an error.

Does %TRIM change the original field?

No. It returns a new value. Assign it to a variable to keep it.

What is the difference between %SUBST and %REPLACE?

%subst reads part of a string. %replace returns a new string with part of the source replaced or with text inserted.

Related BIFs

Summary

2 thoughts on “RPGLE String BIFs Reference”

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top