StrRep: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m ("occurances" -> "occurrences".)
m (changed push calls to add support for usage with " sign)
 
(12 intermediate revisions by 9 users not shown)
Line 1: Line 1:
{{PageAuthor|deguix}}
{{PageAuthor|dandaman32}}


== Description ==
== Description ==
'''Requires:''' [[LogicLib]].
'''Version:''' 2.0.1.
This function searches and replaces all occurrences of a substring in a string.
This function searches and replaces all occurrences of a substring in a string.


== How To Use ==
== How To Use ==


=== Syntax ===
=== Usage / Syntax ===
 
<highlight-nsis>
<highlight-nsis>
${StrRep} "ResultVar" "String" "SubString" "RepString"
${StrRep} '$0' 'C:\Documents and Settings\Dan\Desktop\PSCP Frontend.exe' '\' '\\'
</highlight-nsis>
MessageBox MB_OK $0 ; will be C:\\Documents and Settings\\Dan\\Desktop\\PSCP Frontend.exe
or
<highlight-nsis>
Push "String"
Push "SubString"
Push "RepString"
Call StrRep
Pop "ResultVar"
</highlight-nsis>
</highlight-nsis>


=== Parameters ===
=== Parameters ===


; ResultVar
${StrRep} "$result_var" "String" "SubString" "RepString"
 
; $result_var
: Variable where resulting operation of the replacement is returned. If ''SubString'' is not found, the value is the same as ''String''.
: Variable where resulting operation of the replacement is returned. If ''SubString'' is not found, the value is the same as ''String''.


Line 37: Line 26:


; RepString
; RepString
: String to replace all occurances of ''SubString'' inside ''String''.
: String to replace all occurrences of ''SubString'' inside ''String''.


=== Example ===
=== Example ===


<highlight-nsis>
<highlight-nsis>
${StrRep} $0 "This is just an example" "just" ""
${StrRep} $0 "This is just an example" "just " ""
;$0 = "This is an example"
;$0 = "This is an example"
</highlight-nsis>
</highlight-nsis>
Line 50: Line 39:
<highlight-nsis>
<highlight-nsis>
!define StrRep "!insertmacro StrRep"
!define StrRep "!insertmacro StrRep"
 
!macro StrRep output string old new
!macro StrRep ResultVar String SubString RepString
    Push `${string}`
  Push "${String}"
    Push `${old}`
  Push "${SubString}"
    Push `${new}`
  Push "${RepString}"
    !ifdef __UNINSTALL__
  Call StrRep
        Call un.StrRep
  Pop "${ResultVar}"
    !else
        Call StrRep
    !endif
    Pop ${output}
!macroend
!macroend


Function StrRep
!macro Func_StrRep un
/*After this point:
    Function ${un}StrRep
  ------------------------------------------
        Exch $R2 ;new
  $R0 = RepString (input)
        Exch 1
  $R1 = SubString (input)
        Exch $R1 ;old
  $R2 = String (input)
        Exch 2
  $R3 = RepStrLen (temp)
        Exch $R0 ;string
  $R4 = SubStrLen (temp)
        Push $R3
  $R5 = StrLen (temp)
        Push $R4
  $R6 = StartCharPos (temp)
        Push $R5
  $R7 = TempStrL (temp)
        Push $R6
  $R8 = TempStrR (temp)*/
        Push $R7
        Push $R8
        Push $R9


  ;Get input from user
        StrCpy $R3 0
  Exch $R0
        StrLen $R4 $R1
  Exch
        StrLen $R6 $R0
  Exch $R1
        StrLen $R9 $R2
  Exch
        loop:
  Exch 2
            StrCpy $R5 $R0 $R4 $R3
  Exch $R2
            StrCmp $R5 $R1 found
  Push $R3
            StrCmp $R3 $R6 done
  Push $R4
            IntOp $R3 $R3 + 1 ;move offset by 1 to check the next character
  Push $R5
            Goto loop
  Push $R6
        found:
  Push $R7
            StrCpy $R5 $R0 $R3
  Push $R8
            IntOp $R8 $R3 + $R4
            StrCpy $R7 $R0 "" $R8
            StrCpy $R0 $R5$R2$R7
            StrLen $R6 $R0
            IntOp $R3 $R3 + $R9 ;move offset by length of the replacement string
            Goto loop
        done:
       
        Pop $R9
        Pop $R8
        Pop $R7
        Pop $R6
        Pop $R5
        Pop $R4
        Pop $R3
        Push $R0
        Push $R1
        Pop $R0
        Pop $R1
        Pop $R0
        Pop $R2
        Exch $R1
    FunctionEnd
!macroend
!insertmacro Func_StrRep ""
!insertmacro Func_StrRep "un."


  ;Return "String" if "SubString" is ""
</highlight-nsis>
  ${IfThen} $R1 == "" ${|} Goto Done ${|}


  ;Get "RepString", "String" and "SubString" length
== Versions History ==
  StrLen $R3 $R0
  StrLen $R4 $R1
  StrLen $R5 $R2
  ;Start "StartCharPos" counter
  StrCpy $R6 0


  ;Loop until "SubString" is found or "String" reaches its end
; 4.0 - updated by Marshall
  ${Do}
: Replaced superfluos extra variables with standard registers
    ;Remove everything before and after the searched part ("TempStrL")
: Fixed infinite loop bug where replacement string contained the string-to-replace
    StrCpy $R7 $R2 $R4 $R6
: Structured for installer/uninstaller versions
: Changed macro parameter order to be more intuitive


    ;Compare "TempStrL" with "SubString"
; 3.0.1 - updated by Dan Fuhry
    ${If} $R7 == $R1
: Fixed bug where macro pushed strings in the wrong order
      ;Split "String" to replace the string wanted
      StrCpy $R7 $R2 $R6 ;TempStrL


      ;Calc: "StartCharPos" + "SubStrLen" = EndCharPos
; 3.0 - updated by Dan Fuhry
      IntOp $R8 $R6 + $R4
: Uses less code and doesn't depend on LogicLib
 
: Changed macro syntax to work like the PHP eqivalent
      StrCpy $R8 $R2 "" $R8 ;TempStrR
 
      ;Insert the new string between the two separated parts of "String"
      StrCpy $R2 $R7$R0$R8
      ;Now calculate the new "StrLen" and "StartCharPos"
      StrLen $R5 $R2
      IntOp $R6 $R6 + $R3
      ${Continue}
    ${EndIf}
 
    ;If not "SubString", this could be "String" end
    ${IfThen} $R6 >= $R5 ${|} ${ExitDo} ${|}
    ;If not, continue the loop
    IntOp $R6 $R6 + 1
  ${Loop}
 
  Done:
 
  ;Return output to user
  StrCpy $R0 $R2
 
/*After this point:
  ------------------------------------------
  $R0 = ResultVar (output)*/
 
  Pop $R8
  Pop $R7
  Pop $R6
  Pop $R5
  Pop $R4
  Pop $R3
  Pop $R2
  Pop $R1
  Exch $R0
FunctionEnd
</highlight-nsis>
 
== Versions History ==


;2.0.1
; 2.0.1 - updated by Diego Pedroso
:Fixed stack problems.
: Fixed stack problems


== Credits ==
== Credits ==
Version 4.0 - Marshall ([[User:Marshall|Marshall]]).<br>
Version 3.x - Dan Fuhry ([[User:dandaman32|dandaman32]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 1.x - Hendri Adriaens ([[User:Smile2Me|Smile2Me]]) / [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).
Version 1.x - [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).<br>
Version [http://forums.winamp.com/showthread.php?threadid=83283 1.0] - Hendri Adriaens ([[User:Smile2Me|Smile2Me]])


[[Category:String Functions]]
[[Category:String Functions]]

Latest revision as of 17:26, 29 August 2013

Author: dandaman32 (talk, contrib)


Description

This function searches and replaces all occurrences of a substring in a string.

How To Use

Usage / Syntax

${StrRep} '$0' 'C:\Documents and Settings\Dan\Desktop\PSCP Frontend.exe' '\' '\\'
MessageBox MB_OK $0 ; will be C:\\Documents and Settings\\Dan\\Desktop\\PSCP Frontend.exe

Parameters

${StrRep} "$result_var" "String" "SubString" "RepString"

$result_var
Variable where resulting operation of the replacement is returned. If SubString is not found, the value is the same as String.
String
String where to search for SubString.
SubString
String to search in String and to be replaced by RepString.
RepString
String to replace all occurrences of SubString inside String.

Example

${StrRep} $0 "This is just an example" "just " ""
;$0 = "This is an example"

Function Code

!define StrRep "!insertmacro StrRep"
!macro StrRep output string old new
    Push `${string}`
    Push `${old}`
    Push `${new}`
    !ifdef __UNINSTALL__
        Call un.StrRep
    !else
        Call StrRep
    !endif
    Pop ${output}
!macroend
 
!macro Func_StrRep un
    Function ${un}StrRep
        Exch $R2 ;new
        Exch 1
        Exch $R1 ;old
        Exch 2
        Exch $R0 ;string
        Push $R3
        Push $R4
        Push $R5
        Push $R6
        Push $R7
        Push $R8
        Push $R9
 
        StrCpy $R3 0
        StrLen $R4 $R1
        StrLen $R6 $R0
        StrLen $R9 $R2
        loop:
            StrCpy $R5 $R0 $R4 $R3
            StrCmp $R5 $R1 found
            StrCmp $R3 $R6 done
            IntOp $R3 $R3 + 1 ;move offset by 1 to check the next character
            Goto loop
        found:
            StrCpy $R5 $R0 $R3
            IntOp $R8 $R3 + $R4
            StrCpy $R7 $R0 "" $R8
            StrCpy $R0 $R5$R2$R7
            StrLen $R6 $R0
            IntOp $R3 $R3 + $R9 ;move offset by length of the replacement string
            Goto loop
        done:
 
        Pop $R9
        Pop $R8
        Pop $R7
        Pop $R6
        Pop $R5
        Pop $R4
        Pop $R3
        Push $R0
        Push $R1
        Pop $R0
        Pop $R1
        Pop $R0
        Pop $R2
        Exch $R1
    FunctionEnd
!macroend
!insertmacro Func_StrRep ""
!insertmacro Func_StrRep "un."

Versions History

4.0 - updated by Marshall
Replaced superfluos extra variables with standard registers
Fixed infinite loop bug where replacement string contained the string-to-replace
Structured for installer/uninstaller versions
Changed macro parameter order to be more intuitive
3.0.1 - updated by Dan Fuhry
Fixed bug where macro pushed strings in the wrong order
3.0 - updated by Dan Fuhry
Uses less code and doesn't depend on LogicLib
Changed macro syntax to work like the PHP eqivalent
2.0.1 - updated by Diego Pedroso
Fixed stack problems

Credits

Version 4.0 - Marshall (Marshall).
Version 3.x - Dan Fuhry (dandaman32).
Version 2.x - Diego Pedroso (deguix).
Version 1.x - Afrow UK / Diego Pedroso (deguix).
Version 1.0 - Hendri Adriaens (Smile2Me)