To Shift or Not to Shift: That Is in the Fourth Parameter
April 25, 2007 Ted Holt
RPG’s %REPLACE function is marvelous. When I think of all those array-manipulation calcs I wrote in my System/34 and System/36 days, I could cry. Anyway, to use %REPLACE effectively, it is good to ask oneself a simple question: In the event that the replacement string and the string of characters that is being replaced are not the same length, do I, or do I not, want the characters that follow the replacement to shift? This is the same question SEU asks on the Find/Change Options panel. Informing SEU of your desire is an almost effortless matter of typing a Y or an N into the Allow Data Shift field. Informing %REPLACE of your desire is nearly as easy. Just remember what to place in the fourth parameter. Here are the four parameters defined for %REPLACE:
And here is the rule pertaining to the fourth parameter: To shift, place the length of the string to be replaced in the fourth parameter. To avoid the shift, place the length of the replacement string in the fourth parameter, or omit the fourth parameter. In the following example of excellence in programming, pet is to be replaced with wallaby in the sentence, “My pet’s name is Harold.” D OriginalString s 64a varying D FixedRepl s like(OriginalString) D ShiftRepl s like(OriginalString) D ScanFor s 20a varying D ReplaceWith s 60a varying D Pos s 5i 0 /free OriginalString = 'My pet''s name is Harold.'; ScanFor = 'pet'; ReplaceWith = 'wallaby'; Pos = %scan(ScanFor: OriginalString); ShiftRepl = %replace(ReplaceWith: OriginalString: Pos: %len(ScanFor)); FixedRepl = %replace(ReplaceWith: OriginalString: Pos: %len(ReplaceWith)); FixedRepl = %replace(ReplaceWith: OriginalString: Pos); *inlr = *on; return; The shifted replacement is assigned to the ShiftRepl variable. The unshifted replacement is assigned to FixedRepl. (Both assignments to FixedRepl are identical in function.) Notice what happens. ....5...10...15...20...25...30...35...40 OriginalString My pet's name is Harold. FixedRepl My wallabyame is Harold. ShiftRepl My wallaby's name is Harold. I think shifting is the way to go in this case, don’t you? I also think shifting is the way to go in this case if the replacement string is shorter than the original. Here I replace pet with ma. ....5...10...15...20...25...30...35...40 FixedRepl My mat's name is Harold. ShiftRepl My ma's name is Harold. Of course, one could argue that both versions are invalid, since I have neither a mat nor a mother named Harold. Notice I have used variable-length strings in this example. If you use fixed-length variables, consider using the %TRIMR function in order to ignore trailing blanks, as I illustrate in the following revised example. D OriginalString s 64a D FixedRepl s like(OriginalString) D ShiftRepl s like(OriginalString) D ScanFor s 20a D ReplaceWith s 60a D Pos s 5i 0 /free OriginalString = 'My pet''s name is Harold.'; ScanFor = 'pet'; ReplaceWith = 'buzzard'; Pos = %scan(%trimr(ScanFor): OriginalString); ShiftRepl = %replace(%trimr(ReplaceWith): OriginalString: Pos: %len(%trimr(ScanFor))); FixedRepl = %replace(%trimr(ReplaceWith): OriginalString: Pos: %len(%trimr(ReplaceWith))); FixedRepl = %replace(%trimr(ReplaceWith): OriginalString: Pos); *inlr = *on; return;
|