I'm trying to replace all instances of ~
with {~}
in a batch script so that VBScript doesn't assume I mean to hit enter when I pass it to sendKeys, however, the variable keeps getting replaced by the literal string meant to replace it.
For example,
rem Intended function;
rem input = Hello~world.
rem output = Hello{~}world.
However each time, it either does nothing, or sets refVar to the literal string refVar:~={~}
.
Here's what I have tried;
set refVar=!refVar:~={~}!
rem Also
set refVar=%refVar:~={~}%
rem and...
set refVar=%refVar:^~=^{^~^}%
rem and of course;
set refVar=!refVar:^~=^{^~^}!
rem and even:
set "pre=~"
set "post={~}"
set refVar=%refVar:!pre!=!post!%
rem and the same set commands with;
set refVar=!refVar:%pre%=%post%!
Am I missing a way to escape this? I'm pretty sure it has to do with ~
being a positional character in a similar command.
I understand there's likely a way to fix this in VBScript, but this bothers me to have a restriction without apparent workarounds to me.
So I did some digging and it seems this is really, really hard. However, I did find this, which solves the problem, giving us this as code:
@echo off
set "input=Hello~world."
echo input: %input%
call :wavereplacer "%input%" {tilde} output
set output=%output:{tilde}={~}%
echo output: %output%
pause
::your own code should be above this.
goto :eof
:wavereplacer String Replacer [RtnVar]
setlocal
rem the result of the operation will be stored here
set "result=#%~1#"
set "replacer=%~2"
call :strlen0.3 result wl
call :strlen0.3 replacer rl
:start
set "part1="
set "part2="
rem splitting the string on two parts
for /f "tokens=1* delims=~" %%w in ("%result%") do (
set "part1=%%w"
set "part2=%%x"
)
rem calculating the count replace strings we should use
call :strlen0.3 part1 p1l
call :strlen0.3 part2 p2l
set /a iteration_end=wl-p1l-p2l
rem creating a sequence with replaced strings
setlocal enableDelayedExpansion
set "sequence="
for /l %%i in (1,1,%iteration_end%) do (
set sequence=!sequence!%replacer%
)
endlocal & set "sequence=%sequence%"
rem adjust the string length
set /a wl=wl+iteration_end*(rl-1)
rem replacing for the current iteration
set result=%part1%%sequence%%part2%
rem if the second part is empty the task is over
if "%part2%" equ "" (
set result=%result:~1,-1%
goto :endloop
)
goto :start
:endloop
endlocal & if "%~3" neq "" (set %~3=%result%) else echo %result%
exit /b
:strlen0.3 StrVar [RtnVar]
setlocal EnableDelayedExpansion
set "s=#!%~1!"
set "len=0"
for %%A in (2187 729 243 81 27 9 3 1) do (
set /A mod=2*%%A
for %%Z in (!mod!) do (
if "!s:~%%Z,1!" neq "" (
set /a "len+=%%Z"
set "s=!s:~%%Z!"
) else (
if "!s:~%%A,1!" neq "" (
set /a "len+=%%A"
set "s=!s:~%%A!"
)
)
)
)
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b
This cannot replace ~
to {~}
immediately, you need to use a temporary substitution, in this case {tilde}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With