2

Consider the following code:

@echo off
chcp 65001 >NUL

rem Main thread here which shows how to change each letter to UPPERCASE: https://stackoverflow.com/questions/34713621/batch-converting-variable-to-uppercase
rem Comment here: https://stackoverflow.com/a/34734724/8262102
rem I want to use this code to replace multiple strings but I'm having difficulty
rem with getting % replaced with double % symbols.

set "str=Change %% to double %% and replace other ^(And convert brackets^)"
echo %str% (Old variable)
call :VALIDATE str
echo %str% (New variable)
pause
goto :EOF

:VALIDATE
if not defined %~1 exit /b
for %%A in ("^%^%=^%^%^%^%" "(='('" ")=')'") do (
call set %~1=%%%~1:%%~A%%
)
goto :EOF

This is replacing the ( with '(' and the ) with ')'.

I cannot get % to be replaced with %%.

I've tried to escape the % by using both %% and ^% but no luck at this point in the code "^%^%=^%^%^%^%".

I'm out of ideas as to how to do this.

Ste
  • 1,729
  • 1
  • 17
  • 27

1 Answers1

2

Does this help you at all?

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Set "str=Change %% to %%%%, and %%%% to %%%%%%%%, (and also enclose parentheses in single quotes)."
Echo %str%
Pause

SetLocal EnableDelayedExpansion
Set "str=!str:%%=%%%%!"
Set "str=!str:(='('!"
Set "str=!str:)=')'!"
EndLocal & Set "str=%str%"

Echo %str%
Pause

Or similarly:

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Set "str=Change %% to %%%%, and %%%% to %%%%%%%%, (and also enclose parentheses in single quotes)."
Echo %str% (Old variable)
Call :Validate str
Echo %str% (New variable)
Pause
GoTo :EOF

:Validate
If "%~1" == "" Exit /B
SetLocal EnableDelayedExpansion
Set "_=!%~1!"
Set "_=!_:%%=%%%%!"
Set "_=!_:(='('!"
Set "_=!_:)=')'!"
EndLocal & Set "%~1=%_%"
Exit /B

[EDIT /]

And because …

@Echo Off
SetLocal EnableExtensions DisableDelayedExpansion

Set "str=Change %% to %%%%, and %%%% to %%%%%%%%, (and also enclose parentheses in single quotes)."
Echo %str% (Old variable)
Call :Validate str
Echo %str% (New variable)
Pause
GoTo :EOF

:Validate
If "%~1" == "" Exit /B
SetLocal EnableDelayedExpansion
Set "_=!%~1!"
For %%G In ("%%=%%%%" "(='('" ")=')'") Do Set "_=!_:%%~G!"
EndLocal & Set "%~1=%_%"
Exit /B
Compo
  • 36,585
  • 5
  • 27
  • 39
  • Thanks but I was hoping to retain the same code structure with the for loop and the call if that's possible. – Ste May 24 '20 at 18:30
  • @Ste, I have added an alternative using Call, but I'm not wasting my time with an unnecessary `For` loop. – Compo May 24 '20 at 18:36
  • Thanks. I was hoping to get the for loop working as that's the title of the question as it's a neat way of replacing multiple string. I'll see if I can get it done. – Ste May 24 '20 at 18:55
  • I understand that you want one @Ste, but, as I said, it is unnecessary, _(and your question was technically about '`%` to be replaced with `%%`')_! Your for loop is effectively performing three commands, I've just used the same three commands! Why do you think you need one? I've done you the courtesy of adding it as an [EDIT /] regardless. – Compo May 24 '20 at 19:07
  • Ah, just because it's a neat solution. Thanks. I'll try to wrap my head around how that worked and mine didn't. I think it's due to `SetLocal EnableDelayedExpansion` and then expanding the variable `%~1`. Great answer. – Ste May 24 '20 at 19:32
  • Whilst I appreciate your acceptance of the solution and feedback @Ste, just be aware that if you're wanting to use the idea as a robust solution in anything other than a test environment, you should really expand the code to first determine that any instances of `(`, or `)`, are not already preceded and/or succeeded by single quotes, _(so that you don't end up doubling those)_. I'll leave that decision and coding to you however. – Compo May 24 '20 at 19:34