Page 1 of 1

Replace only the first occurrence of a string

Posted: Fri Jan 18, 2008 9:59 pm
by Mistrel
This function can be used to replace the first occurrence of a key string. This function is case insensitive

Code: Select all

Procedure.s ReplaceFirstCase(String.s,StringToFind.s,StringToReplace.s)
	pos=FindString(LCase(String.s),LCase(StringToFind.s),1)
	If Not pos
		ProcedureReturn: EndIf
	left.s=Left(String.s,pos-1)
	right.s=Right(String.s,Len(String.s)-pos-Len(StringToFind.s)+1)
	String.s=left.s+StringToReplace.s+right.s
	ProcedureReturn String.s
EndProcedure

Posted: Fri Jan 18, 2008 11:10 pm
by rsts
Thanks for sharing.

String functions always come in handy. :)

cheers

Posted: Sat Jan 19, 2008 10:54 am
by superadnim
This should be a tiny faster (~1.5x) and more flexible than the OP's solution, but please don't hesitate to further optimize it.

Code: Select all

Procedure.s StringReplace( szStr.s, szStrSrc.s, szStrRepl.s, dwTimes=1 )
   
   Define.l dwPos, i
   
   #OPT_EARLYOUT   = #True
   CompilerIf #OPT_EARLYOUT = #True
      If CountString(szStr, szStrSrc) = dwTimes ;early-out
         ProcedureReturn ReplaceString(szStr, szStrSrc, szStrRepl)
      EndIf
   CompilerEndIf
   
   For i=1 To dwTimes
      dwPos   = FindString(szStr, szStrSrc, 1)
      If  dwPos
         szStr = Left(szStr, dwPos-1) + szStrRepl + Right(szStr, (Len(szStr)-dwPos-Len(szStrSrc)+1) )
      Else
         Break
      EndIf
    Next
   
   ProcedureReturn szStr
   
EndProcedure

The purpose of this routine is to allow you to define how many replace steps to do before returning the processed string. It has an early-out just to prevent doing the whole manual replace, but I strongly advise you to avoid using this routine if you know you'll be replacing all occurrences in the source string (use ReplaceString instead) . If you don't need the early-out, you can set the constant to 0. Only do this if you know you won't need the case.


For a faster version (~2.5x) of the original routine, this should do the trick:

Code: Select all

Procedure.s StringReplaceFirst( szStr.s, szStrSrc.s, szStrRepl.s )
   
   Define.l dwPos
   
   dwPos	= FindString(szStr, szStrSrc, 1)
   If dwPos
   	ProcedureReturn Left(szStr, dwPos-1) + szStrRepl + Right(szStr, (Len(szStr)-dwPos-Len(szStrSrc)+1) )
   EndIf
   
EndProcedure
Hope that helps :)

Cheers