StrRep: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
m (Corrected link to LogicLib header file.)
No edit summary
Line 1: Line 1:
{{PageAuthor|deguix}}
{{PageAuthor|dandaman32}}


== Description ==
== Description ==


'''Requires:''' [[LogicLib header file]].
'''Version: 3.0'''
 
'''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.
Line 13: Line 11:
=== Syntax ===
=== Syntax ===


; Single command
: This is by far the easiest way to use StrReplace.
<highlight-nsis>
<highlight-nsis>
${StrRep} "ResultVar" "String" "SubString" "RepString"
${StrReplace} '$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
</highlight-nsis>
</highlight-nsis>
or
 
; Push/function call
: For when you're used to NSIS :)
<highlight-nsis>
<highlight-nsis>
Push "String"
Push "old"
Push "SubString"
Push "brand new"
Push "RepString"
Push "Shame on you, you broke your old needle!"
Call StrRep
Call StrReplace
Pop "ResultVar"
Pop $0
MessageBox MB_OK $0 ; will be "Shame on you, you broke your brand new needle!"
</highlight-nsis>
</highlight-nsis>
; Usage
: ${StrReplace} "$result_var" "SubString" "RepString" "String"


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


; ResultVar
; $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 42: Line 49:


<highlight-nsis>
<highlight-nsis>
${StrRep} $0 "This is just an example" "just" ""
${StrReplace} $0 "just " "" "This is just an example"
;$0 = "This is an example"
;$0 = "This is an example"
</highlight-nsis>
</highlight-nsis>
Line 49: Line 56:


<highlight-nsis>
<highlight-nsis>
!define StrRep "!insertmacro StrRep"
; StrReplace
 
; Replaces all ocurrences of a given needle within a haystack with another string
!macro StrRep ResultVar String SubString RepString
; Written by dandaman32
  Push "${String}"
  Push "${SubString}"
  Push "${RepString}"
  Call StrRep
  Pop "${ResultVar}"
!macroend


Function StrRep
Var STR_REPLACE_VAR_0
/*After this point:
Var STR_REPLACE_VAR_1
  ------------------------------------------
Var STR_REPLACE_VAR_2
  $R0 = RepString (input)
Var STR_REPLACE_VAR_3
  $R1 = SubString (input)
Var STR_REPLACE_VAR_4
  $R2 = String (input)
Var STR_REPLACE_VAR_5
  $R3 = RepStrLen (temp)
Var STR_REPLACE_VAR_6
  $R4 = SubStrLen (temp)
Var STR_REPLACE_VAR_7
  $R5 = StrLen (temp)
Var STR_REPLACE_VAR_8
  $R6 = StartCharPos (temp)
  $R7 = TempStrL (temp)
  $R8 = TempStrR (temp)*/


  ;Get input from user
Function StrReplace
   Exch $R0
   Exch $STR_REPLACE_VAR_2
   Exch
   Exch 1
   Exch $R1
   Exch $STR_REPLACE_VAR_1
  Exch
   Exch 2
   Exch 2
   Exch $R2
   Exch $STR_REPLACE_VAR_0
  Push $R3
    StrCpy $STR_REPLACE_VAR_3 -1
  Push $R4
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
  Push $R5
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
   Push $R6
    loop:
   Push $R7
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
   Push $R8
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
   Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
   Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
   Exch $STR_REPLACE_VAR_0
FunctionEnd


   ;Return "String" if "SubString" is ""
!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
   ${IfThen} $R1 == "" ${|} Goto Done ${|}
   Push "${NEEDLE}"
   Push "${NEEDLE2}"
  Push "${HAYSTACK}"
  Call StrReplace
  Pop "${OUT}"
!macroend


  ;Get "RepString", "String" and "SubString" length
!define StrReplace '!insertmacro "_strReplaceConstructor"'
  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
  ${Do}
    ;Remove everything before and after the searched part ("TempStrL")
    StrCpy $R7 $R2 $R4 $R6
 
    ;Compare "TempStrL" with "SubString"
    ${If} $R7 == $R1
      ;Split "String" to replace the string wanted
      StrCpy $R7 $R2 $R6 ;TempStrL
 
      ;Calc: "StartCharPos" + "SubStrLen" = EndCharPos
      IntOp $R8 $R6 + $R4
 
      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>
</highlight-nsis>


== Versions History ==
== Versions History ==
; 3.0
: Updated by dandaman32 - uses less code and doesn't depend on LogicLib
: Also: changed macro syntax to work like the PHP eqivalent


;2.0.1
;2.0.1
Line 152: Line 119:


== Credits ==
== Credits ==
Version 3.x - Dan Fuhry ([[User:dandaman32]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 2.x - Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 1.x [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).<br>
Version 1.x [[User:Afrow UK|Afrow UK]] / Diego Pedroso ([[User:deguix|deguix]]).<br>

Revision as of 07:27, 18 March 2006

Author: dandaman32 (talk, contrib)


Description

Version: 3.0

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

How To Use

Syntax

Single command
This is by far the easiest way to use StrReplace.
${StrReplace} '$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
Push/function call
For when you're used to NSIS :)
Push "old"
Push "brand new"
Push "Shame on you, you broke your old needle!"
Call StrReplace
Pop $0
MessageBox MB_OK $0 ; will be "Shame on you, you broke your brand new needle!"
Usage
${StrReplace} "$result_var" "SubString" "RepString" "String"

Parameters

$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

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

Function Code

; StrReplace
; Replaces all ocurrences of a given needle within a haystack with another string
; Written by dandaman32
 
Var STR_REPLACE_VAR_0
Var STR_REPLACE_VAR_1
Var STR_REPLACE_VAR_2
Var STR_REPLACE_VAR_3
Var STR_REPLACE_VAR_4
Var STR_REPLACE_VAR_5
Var STR_REPLACE_VAR_6
Var STR_REPLACE_VAR_7
Var STR_REPLACE_VAR_8
 
Function StrReplace
  Exch $STR_REPLACE_VAR_2
  Exch 1
  Exch $STR_REPLACE_VAR_1
  Exch 2
  Exch $STR_REPLACE_VAR_0
    StrCpy $STR_REPLACE_VAR_3 -1
    StrLen $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_1
    StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
    loop:
      IntOp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_3 + 1
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_4 $STR_REPLACE_VAR_3
      StrCmp $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_1 found
      StrCmp $STR_REPLACE_VAR_3 $STR_REPLACE_VAR_6 done
      Goto loop
    found:
      StrCpy $STR_REPLACE_VAR_5 $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_3
      IntOp $STR_REPLACE_VAR_8 $STR_REPLACE_VAR_3 + $STR_REPLACE_VAR_4
      StrCpy $STR_REPLACE_VAR_7 $STR_REPLACE_VAR_0 "" $STR_REPLACE_VAR_8
      StrCpy $STR_REPLACE_VAR_0 $STR_REPLACE_VAR_5$STR_REPLACE_VAR_2$STR_REPLACE_VAR_7
      StrLen $STR_REPLACE_VAR_6 $STR_REPLACE_VAR_0
      Goto loop
    done:
  Pop $STR_REPLACE_VAR_1 ; Prevent "invalid opcode" errors and keep the
  Pop $STR_REPLACE_VAR_1 ; stack as it was before the function was called
  Exch $STR_REPLACE_VAR_0
FunctionEnd
 
!macro _strReplaceConstructor OUT NEEDLE NEEDLE2 HAYSTACK
  Push "${NEEDLE}"
  Push "${NEEDLE2}"
  Push "${HAYSTACK}"
  Call StrReplace
  Pop "${OUT}"
!macroend
 
!define StrReplace '!insertmacro "_strReplaceConstructor"'

Versions History

3.0
Updated by dandaman32 - uses less code and doesn't depend on LogicLib
Also: changed macro syntax to work like the PHP eqivalent
2.0.1
Fixed stack problems.

Credits

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