%INSTR
Search for a substring within a string
WTSupported in traditional Synergy on Windows
|
WNSupported in Synergy .NET on Windows
|
USupported on UNIX
|
VSupported on OpenVMS
|
position = %INSTR(start, string, substring[, position2])
or
xcall INSTR(start, string, substring, position2)
Return value
position
The starting position of the first occurrence of substring within string. (n)
If any of the following conditions are true, the result is 0:
- Start is less than or equal to 0.
- String is null.
- Substring isn’t found within the search range of string.
- Start is greater than the length of string.
If substring is null but string is not, the result is 1. If position2 is specified, the result is also returned in that variable.
Arguments
start
The position in the string at which the search will begin. (n)
string
The string in which to search for the substring. (a)
substring
The substring for which to search. (a)
position2
(optional) A variable in which to return the starting position of the first occurrence of substring. If INSTR can’t find an exact match of the substring value or matches one of the other conditions described by position, position2 is returned with a value of 0 to indicate that the search failed. (n)
Discussion
Searching from left to right, %INSTR searches for substring in string from start through the end of the string. The length of substring must be less than or equal to the length of string.
To search from right to left and find the last occurrence of the substring, use %RVSTR.
The position returned is relative to the beginning of string.
Examples
This function checks if the entered state abbreviation is in the western part of the United States.
function chk_state a_state ,a record western ,a*, "AZ|CA|CO|ID|MT|NM|NV|OR|UT|WA|WY" proc freturn %instr(1, western, a_state) endfunction
In the example below, assume your data division looks like this:
record codes ,a30, "help.add.sub.mul.div" loc ,d3 target ,a3, "sub"
The following subroutine returns a loc value of 7, because the first d appears at character position 7 in the string stored in the codes variable.
xcall instr(4, codes, "d", loc)
The subroutine below assigns the value 8 to loc, because when the search begins at the eighth character stored in codes, the first d appears at character position 8. This result differs from the preceding XCALL, because the starting position value causes the search to begin after the d in character position 7.
xcall instr(8, codes, "d", loc)
The following subroutine searches codes for the first occurrence of sub, beginning at character position 1. Loc is set to 10.
xcall instr(1, codes, target, loc)
The example below uses one field for all of the error messages, rather than a separate field or array entry for each message. This saves data space, because the field is the exact size of the error message, with no filler. The processing method uses delimiters that make it easy to add, delete, or change error messages.
subroutine error_msg err_code ,a ;Error code, including colon .define TTY ,1 ;Terminal channel .define FILEOF ,1 ;End-of-file error # .define ROW ,12 ;Row # to display error message record err_msg ;Capitalized word is err_code ,a*, "Opener:Could not open file\" & "FLESIZ:File full\" & "DUPKEY:Duplicate key exists\" & "KEYSIZ:Incorrect key size\" & "NOTFOUND:Record not found\" & "LOCKED:Record locked--try again\" & "ILLRECNBR:Invalid record number\" & "WRONG:Invalid error code\" & "CNTLC:Internal error--call developer!\" record msg_buffer ret_msg ,a22, "Press <CR> to Continue" input ,a1 ;Dummy input variable start_pos ,d4 ;Start position of error message end_pos ,d4 ;End position of error message len ,d2 ;Length of error message record window width ,d2 ;Width of error msg display col ,d2 ;Column position of error msg proc onerror (FILEOF)done, exit ;Look for valid error code xcall instr(1, err_msg, err_code, start_pos) len = %size(err_code) if (start_pos .eq. 0) begin len = 6 ;Length of "WRONG:" xcall instr(1, err_msg, "WRONG:", start_pos) end xcall instr(start_pos + len, err_msg, '\', end_pos) decr end_pos ;Back up to end of msg start_pos = start_pos + len width = end_pos - start_pos + 1 ;Error msg width col = %rnd(40.0 - width/2.0) display(TTY, $scr_pos(ROW, col), & err_msg(start_pos, end_pos), & $scr_pos(ROW + 1, 28), ret_msg) reads(TTY, input, done) ;Wait for user response done, ;Error displayed offerror xreturn exit, ;If anything unexpected happens, stop program offerror xcall exit_sys ;External wrap up stop endsubroutine