Replace only the first occurrence of a string

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Replace only the first occurrence of a string

Post 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
rsts
Addict
Addict
Posts: 2736
Joined: Wed Aug 24, 2005 8:39 am
Location: Southwest OH - USA

Post by rsts »

Thanks for sharing.

String functions always come in handy. :)

cheers
superadnim
Enthusiast
Enthusiast
Posts: 480
Joined: Thu Jul 27, 2006 4:06 am

Post 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
Post Reply