Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

String Replacement Routine

16 views
Skip to first unread message

Frank P. Westlake

unread,
Nov 24, 2009, 4:09:16 AM11/24/09
to
This string replacement routine seems able to handle any characters if
they are properly entered into variables.

The routine is written as a subroutine which would be added to a script
and called from within the script. Documentation is included with the
subroutine.

The subroutine is presented here as part of a demonstraton script. This
demonstration will begin with the string:

"@#$%%"^&*(!)_-+={[}]|\:;'<,>.?/!

Notice that the string contains quotes (") and an unescaped exclamation
mark (!). Also notice that the percent sign (%) is properly escaped by a
percent sign; this is necessary only from within a script. The string
also contains many other characters which normally foul string
replacement.

The demonstration converts that string by parts to

'[1]'[2][3][4]

Then that converted string is sent through the reverse process and
converted back to how it began.

The demonstration should print:

BEGIN: v="@#$%"^&*(!)_-+={[}]|\:;'<,>.?/!
REPLACED: v='[1]'[2][3][4]
RESTORED: v="@#$%"^&*(!)_-+={[}]|\:;"<,>.?/!

In nearly all of my work in creating this routine I used strings of
special characters, so I would not be surprised if the routine fails
with normal characters.

:: BEGIN SCRIPT ::::::::::::::::::::::::::::::::::::::::::::
@echo OFF
SetLocal ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
Set "v="@#$%%"^&*(!)_-+={[}]|\:;'<,>.?/!"
SetLocal EnableDelayedExpansion & Echo.BEGIN: v=!v! & EndLocal
Set "e=@#$%%" & Set "d=[1]"
Call :ReplaceString v e d
Set "e=^" & Set "d=[2]"
Call :ReplaceString v e d
Set "e=&*(^!)_-+={[}]|\:;'<,>.?/" & Set "d=[3]"
Call :ReplaceString v e d
Set "e=^!" & Set "d=[4]"
Call :ReplaceString v e d
(Set e=^")& Set "d='"
Call :ReplaceString v e d
SetLocal EnableDelayedExpansion & Echo.REPLACED: v=!v! & EndLocal
Set "e=[1]" & Set "d=@#$%%"
Call :ReplaceString v e d
Set "e=[2]" & Set "d=^"
Call :ReplaceString v e d
Set "e=[3]" & Set "d=&*(^!)_-+={[}]|\:;'<,>.?/"
Call :ReplaceString v e d
Set "e=[4]" & Set "d=^!"
Call :ReplaceString v e d
Set "e='" & (Set d=^")
Call :ReplaceString v e d
SetLocal EnableDelayedExpansion & Echo.RESTORED: v=!v! & EndLocal
Goto :EOF


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ReplaceString string_var find_var [replace_var]
:: Replaces selected components of a string within a variable.
:: PARAMETERS
:: 1: The name of the variable containing the string.
:: 2: The name of the variable containing the component to
:: be replaced by the contents of parameter 3.
:: 3: The name of the variable containing the string to replace
:: components identified by the contents of parameter 2.
:: This parameter is optional. If it is absent then the
:: components identified by parameter 2 will be deleted
:: from the string.
:: REMARKS
:: All strings require normal entry precautions. The percent sign
:: (%) must be doubled when entered within a script:
:: SET "STRING=50%%"
::If parameter 1 or parameter 2 contain the exclamation mark (!)
::it must be escaped:
:: SET "FIND=^!"
::Strings entered from the command line or from a file may not
::need such treatment.
::EXAMPLE
:: SET "string=A 50%% increase!" & SET "find=50" & SET "replace=500"
:: Call :ReplaceString string find replace
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "old=!%~1!" & Set "new=" & Set "r2=" & Set "r3=" & Set "skip=0"
If DEFINED %~2 For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b")
If DEFINED %~3 For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b")
Set "s=0"&For /F "tokens=1* delims=:" %%a in (
'(Set old^& Echo.^)^|FindStr /O .') Do (
If !s! EQU 1 (Set /A "s=%%a-6") Else (Set /A "s+=1"))
Set "o=0"&If DEFINED r2 (For /F "tokens=1* delims=:" %%a in (
'(Set r2^& Echo.^)^|FindStr /O .') Do (
If !o! EQU 1 (Set /A "o=%%a-5") Else (Set /A "o+=1")))
For /L %%i in (0,1,%s%) Do (
If !skip! EQU 0 (
If "!old:~%%i,%o%!" EQU "!r2!" (
Set "new=!new!!r3!" & Set /A "skip=%o%-1"
) Else (
Set "new=!new!!old:~%%i,1!"
)
) Else (Set /A "skip-=1")
)
For /F "tokens=1* delims==" %%a in ('Set new') Do (
EndLocal
Set "%~1=%%b"&Goto %0.break
)
:ReplaceString.break
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

::Frank
::L�mpimin terveisin


Frank P. Westlake

unread,
Nov 24, 2009, 5:46:33 AM11/24/09
to
Here is a demonstration of string replacement in a file. The
demonstration writes each line to the console but they could be
redirected to a file.

There are a lot of strings to search for in each line so it is slow.

:: BEGIN SCRIPT ::::::::::::::::::::::::::::::::::::::::::::
@echo OFF
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
Set "OrigFile=demo1.txt"
Set "DestFile=CON:"
:: Create a file:
(
Echo.To be, or not to be: that is the question:
Echo.Whether 'tis nobler in the mind to suffer
Echo.The slings and arrows of outrageous fortune,
Echo.Or to take arms against a sea of troubles,
Echo.And by opposing end them? To die: to sleep;
Echo.No more; and by a sleep to say we end
Echo.The heart-ache and the thousand natural shocks
Echo.That flesh is heir to, 'tis a consummation
Echo.Devoutly to be wish'd. To die, to sleep;
Echo.To sleep: perchance to dream: ay, there's the rub;
Echo.For in that sleep of death what dreams may come
Echo.When we have shuffled off this mortal coil,
Echo.Must give us pause: there's the respect ...
Echo.
Echo.William Shakespere
)>%OrigFile%
Type "%OrigFile%" & Type NUL:>"%DestFile%"
Set /A "i=0, StringCount=0, name=0"
::Replacement strings:
::FIND REPLACE
For %%a in (
be DEL
slings bits
arrows bytes
"outrageous fortune" "wasted space"
troubles files
die DEL
William Frank
"a sleep" cleaning
"sleep of" "cleaning of"
sleep clean
heart-ache corruption
"the thousand natural shocks" fragmentation
"flesh is" "disks are"
dreams freeing
dream free
death DEL
"mortal coil" "magnetic spoil"
Shakespere Westlake
pause PAUSE
"DEL wi" "be wi"
) Do (
Set "Parameter!StringCount!.!name!=%%~a"
Set /A "StringCount+=i&1, i+=1, name=i&1"
)
Set /A "n=StringCount-1"
Echo.*********************************************


For /F "tokens=1* delims=:" %%a in (

'FindStr/n "^" "%OrigFile%"') Do (
Set "line=%%b"
If DEFINED line (
For /L %%i in (0,1,%n%) Do (
Call :ReplaceString line parameter%%i.0 parameter%%i.1
)
)
Echo.!line!>>"%DestFile%"
)
Echo.*********************************************
If /I "%DestFile%" NEQ "CON:" (
Type "%DestFile%"
Erase "%OrigFile%" "%DestFile%"
)

::Frank
::Cordiales salutations


Frank P. Westlake

unread,
Nov 24, 2009, 5:54:33 AM11/24/09
to
"Frank P. Westlake" news:hegdia$nj9$1...@news.albasani.net...

> If /I "%DestFile%" NEQ "CON:" (
> Type "%DestFile%"
> Erase "%OrigFile%" "%DestFile%"
> )

Please change to:

If /I "%DestFile%" NEQ "CON:" (
Type "%DestFile%"

Erase "%DestFile%"
)
Erase "%OrigFile%"

Frank
garma sambandha


Frank P. Westlake

unread,
Nov 24, 2009, 9:34:11 AM11/24/09
to
Added the optional parameter /I as te first parameter to ignore case of
test in the input string. This is now version 1.0 so I guess the
previous must have been 0 or less.

Frank
Warm horfa


::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ReplaceString [/I] string_var find_var [replace_var]
:: V 1.0 Frank P. Westlake, 2009-11-24


:: Replaces selected components of a string within a variable.
:: PARAMETERS

:: /I Ignore case of characters in string_var. This
:: parameter is optional but can only be the first
:: parameter.
:: string_var The name of the variable containing the string.
:: find_var The name of the variable containing the component
:: to be replaced by the contents of replace_var.
:: replace_var The name of the variable containing the string to


:: replace components identified by the contents of

:: find_var. This parameter is optional. If it is
:: absent then the components identified by find_var
:: will be deleted from the string.
:: REMARKS
:: - All strings require normal entry precautions. The percent sign


:: (%) must be doubled when entered within a script:
:: SET "STRING=50%%"

:: - If find_var or replace_var contain the exclamation mark (!) it


:: must be escaped:
:: SET "FIND=^!"

:: - Strings entered from the command line or from a file may not


:: need such treatment.
::EXAMPLE
:: SET "string=A 50%% increase!" & SET "find=50" & SET "replace=500"
:: Call :ReplaceString string find replace
::
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

If /I "%~1" EQU "/I" (Set "I=/I" & SHIFT) Else (Set "I=")


Set "old=!%~1!" & Set "new=" & Set "r2=" & Set "r3=" & Set "skip=0"
If DEFINED %~2 For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b")
If DEFINED %~3 For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b")
Set "s=0"&For /F "tokens=1* delims=:" %%a in (
'(Set old^& Echo.^)^|FindStr /O .') Do (
If !s! EQU 1 (Set /A "s=%%a-6") Else (Set /A "s+=1"))
Set "o=0"&If DEFINED r2 (For /F "tokens=1* delims=:" %%a in (
'(Set r2^& Echo.^)^|FindStr /O .') Do (
If !o! EQU 1 (Set /A "o=%%a-5") Else (Set /A "o+=1")))
For /L %%i in (0,1,%s%) Do (

If !skip! EQU 0 (If %I% "!old:~%%i,%o%!" EQU "!r2!" (


Set "new=!new!!r3!" & Set /A "skip=%o%-1"
) Else (Set "new=!new!!old:~%%i,1!")) Else (Set /A "skip-=1"))
For /F "tokens=1* delims==" %%a in ('Set new') Do (

EndLocal & Set "%~1=%%b"&Goto ReplaceString.break)
:ReplaceString.break
Goto :EOF
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


sw0rdfish

unread,
Nov 25, 2009, 9:20:48 PM11/25/09
to
On Nov 24, 5:09 pm, "Frank P. Westlake" <frank.westl...@yahoo.com>
wrote:

> This string replacement routine seems able to handle any characters if
> they are properly entered into variables.

I will use your script only when all other programming languages
better at this goes extinct. :)

Frank P. Westlake

unread,
Nov 28, 2009, 10:49:24 AM11/28/09
to
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: ReplaceString [/I] string_var find_var [replace_var]
:: V 1.1 Frank P. Westlake, 2009-11-24. See changes at :EOF

:: Replaces selected components of a string within a variable.
:: PARAMETERS
:: /I Ignore case of characters in string_var. This
:: parameter is optional but can only be the first
:: parameter.
:: string_var The name of the variable containing the string.
:: find_var The name of the variable containing the component
:: to be replaced by the contents of replace_var.
:: replace_var The name of the variable containing the string to

:: replace components identified by the contents of
:: find_var. This parameter is optional. If it is
:: absent then the components identified by find_var
:: will be deleted from the string.
:: REMARKS
:: - All strings require normal entry precautions. The percent sign

:: (%) must be doubled when entered within a script:
:: SET "STRING=50%%"
:: - If find_var or replace_var contain the exclamation mark (!) it

:: must be escaped:
:: SET "FIND=^!"
:: - Strings entered from the command line or from a file may not

:: need such treatment.
::EXAMPLE
:: SET "string=A 50%% increase!" & SET "find=50" & SET "replace=500"
:: Call :ReplaceString string find replace
:ReplaceString String_Name Find_Name Replace_Name
SetLocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
If /I "%~1" EQU "/I" (Set "I=/I" & SHIFT) Else (Set "I=")
Set "old=!%~1!" & Set "new=" & Set "r2=" & Set "r3=" & Set "skip=0"
If DEFINED %~2 For /F "tokens=1* delims==" %%a in ('Set %~2') Do (
If NOT DEFINED r2 Set "r2=%%b")
If DEFINED %~3 For /F "tokens=1* delims==" %%a in ('Set %~3') Do (
If NOT DEFINED r3 Set "r3=%%b")
Set /A "s=0,t=0"&For /F "tokens=1* delims=:" %%a in (
'(Set old^& Echo.^)^|FindStr /O .') Do (Set /A "t+=1"
If !t! EQU 2 (Set /A "s=%%a-6"))
Set /A "o=0,t=0"&If DEFINED r2 (For /F "tokens=1* delims=:" %%a in (
'(Set r2^& Echo.^)^|FindStr /O .') Do (Set /A "t+=1"
If !t! EQU 2 (Set /A "o=%%a-5")))

For /L %%i in (0,1,%s%) Do (
If !skip! EQU 0 (If %I% "!old:~%%i,%o%!" EQU "!r2!" (

Set "new=!new!!r3!" & Set /A "skip=%o%-1"
) Else (Set "new=!new!!old:~%%i,1!")) Else (Set /A "skip-=1"))
For /F "tokens=1* delims==" %%a in ('Set new') Do (
EndLocal & Set "%~1=%%b"&Goto ReplaceString.break)
:ReplaceString.break
Goto :EOF
::CHANGES:
:: V1.1 2009-11-28 Changed string length routines to avoid
:: measuring multiple variables.
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::


0 new messages