Mart
(KiX Supporter)
2009-08-28 09:08 AM
Replace function in 4.61 RC1 gives incorrect results.

The replace function is nice but I do not get correct results.

Running the example from kix2010.txt

 Code:
REPLACE("string with another string in it", "string", "STRING", 1)


gives me

 Quote:

STRING with another STRING in it


should be
 Quote:

STRING with another string in it


Ruud van Velsen
(Hey THIS is FUN)
2009-08-28 06:21 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

Ah, the example is bad... Offset 1 points to the first character in the input string (just as with SUBSTR), not the second one (as in C/C++).

So REPLACE("string with another string in it", "string", "STRING", 2) is the right example.

I'll fix this in the final version of the document.

Thanks for the report!

Ruud


Glenn BarnasAdministrator
(KiX Supporter)
2009-08-29 01:57 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

Ah - so the function logic is actually:
 Code:
REPLACE - replace all occurrences of a substring with a new substring, starting at a specified character position.
REPLACE(InputString, OldString, NewString, Char_Offset)
Examples:

    REPLACE("string with another string in it", "string", "STRING")                 ; "STRING with another STRING in it"
    REPLACE("string with another string in it", "string", "STRING", 2)              ; "string with another STRING in it"
    REPLACE("string with another string in it", "string", "")                       ; " with another  in it"
The original description text is a bit misleading.
Glenn


Mart
(KiX Supporter)
2009-08-29 02:55 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

Thanks for the explanation.

AllenAdministrator
(KiX Supporter)
2009-08-29 04:08 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

REPLACE("string with another string in it", "string", "STRING", 2) ; "STRING with another string in it"

I think Glenn is right, but the example is wrong. Should be
"string with another STRING in it"

So is offset what we really want though? Seems like it might be either count(like Split and Join behavior), or skip(skip x number of results before the first replace).

TBH I'm really trying to think of a time when I would have ever used any of these when I am replacing.


Glenn BarnasAdministrator
(KiX Supporter)
2009-08-29 06:38 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

Right, missed that. I fixed the example in my post. I just copied/pasted Ruud's example at first.

I agree - Replace() without the offset just simplifies Join/Split. I can only think of a few times where I didn't need to make a global replacement.

Honestly, what would make the most sense to me is
Replace(Source, Substring1, Substring2, Offset, Count)
which would search Source for Substring1, replacing it with Substring2, but only from the Offset position (or N'th occurrence) and only process Count replacements. Without a Count parameter, Offset doesn't seem to have as much value.

Here's a UDF with sample code that illustrates my thoughts using "N'th Occurrence" and "Count" optional parameters:

break on
 
'Replace all occurrences:' ?
; StringReplace('string with another string in the string', 'strong', 'STRONG') ? 
StringReplace('string with another string in the string', 'string', 'STRING') ?
StringReplace('string with another string in the string text', 'string', 'STRING') ?
StringReplace('text string with another string in the string text', 'string', 'STRING') ?
?
'Replace all occurrences, starting with the second:' ?
StringReplace('string with another string in the string', 'string', 'STRING', 2) ?
StringReplace('string with another string in the string text', 'string', 'STRING', 2) ?
StringReplace('text string with another string in the string text', 'string', 'STRING', 2) ?
?
'Replace only the second occurrence:' ?
StringReplace('string with another string in the string', 'string', 'STRING', 2, 1) ?
StringReplace('string with another string in the string text', 'string', 'STRING', 2, 1) ?
StringReplace('text string with another string in the string text', 'string', 'STRING', 2, 1) ?
 
 
 
 
 
Function StringReplace($_Source, $_S1, $_S2, Optional $_Start, Optional $_Count)
 
  Dim $_Case						; current CASE setting 
  Dim $_aSource						; array of source string components 
  Dim $_I						; index pointer 
  Dim $_Min, $_Max					; min and max process values 
 
  $_Case = SetOption('CaseSensitivity', 'On')		; insure case-specific matching 
 
  $_aSource = Split($_Source, $_S1)			; break source sting into array 
  $_Min = 0						; Start processing here 
  $_Max = UBound($_aSource)				; end processing here 
  $_Start = IIf($_Start, $_Start - 1, 0)		; make the supplied start value 0-based 
 
  ; define the Count value to ALL if not specified 
  $_Count = IIf($_Count, $_Count, $_Max)
  If $_Count > $_Max
    $_Count = $_Max					; don't allow a greater count than elements 
  EndIf
 
  ; handle situations where the first element is a replacement value 
  If $_aSource[0] = ''
    If $_Start = 0 And $_Count				; see if we should replace based on start and count 
      $StringReplace = $StringReplace + $_S2		; REPLACE! 
      $_Count = $_Count - 1				; reduce the count 
    Else
      $StringReplace = $StringReplace + $_S1		; original text - no replacement 
    EndIf
    $_Min = 1						; skip the first element in the loop 
  EndIf
 
  For $_I = $_Min to $_Max
    $StringReplace = $StringReplace + $_aSource[$_I]	; add original text component 
    If $_I < $_Max And $_aSource[$_I]			; handle replacable last element 
      If $_I >= $_Start And $_Count			; see if we should replace based on start and count 
        $StringReplace = $StringReplace + $_S2		; REPLACE! 
        $_Count = $_Count - 1				; reduce count 
      Else
        $StringReplace = $StringReplace + $_S1		; original text, no replacement 
      EndIf
    EndIf
  Next
 
  $_Case = SetOption('CaseSensitivity', $_Case)		; restore original value 
 
  Exit 0
 
EndFunction
 
 
 
Just my opinion..

Glenn

Ruud van Velsen
(Hey THIS is FUN)
2009-08-30 12:53 PM
Re: Replace function in 4.61 RC1 gives incorrect results.

Phhh... I just need to work on documenting these things better: the Replace function features not just an offset parameter, but also a count parameter. Exactly as you describe above. The manual has the correct description, it's the readme that's confusing.

Ruud