Page 1 of 1

replace a substring by position

Posted: 01 Feb 2012 08:38
by atamo
I want to replace a string second character with somthing else, e.g. :

set cmd /E:ON
set var=asdfg
echo !var:!var:~1,1!=OK!

unfortunately don't replace s with OK , the code display

Code: Select all

!var:s=OK!
but I want

Code: Select all

aOKdfg


thank's your help .

Re: replace a substring by position

Posted: 01 Feb 2012 08:49
by Squashman

Code: Select all

H:\>set var=asdfg

H:\>set var=%var:s=OK%

H:\>echo %var%
aOKdfg

Re: replace a substring by position

Posted: 01 Feb 2012 10:02
by dbenham
Squashman's solution searches for a substring and replaces it with something else.

You want to replace based on position, not a substring.

You attempted to use delayed expansion (which is a good idea if you are dealing with special characters like ^ & > | < etc.) But you did not enable delayed expansion properly. Your substring syntax was also incorrect.

You can't really replace a character by position like that. Instead you have to build a new string by concatenating the beginning substring, your new text, and then the final substring.

From the command line you could do

Code: Select all

cmd /v:on
set var=asdfg
echo !var:~0,1!OK!!var:~2!


Normally you would do something like this from a batch file, in which case you can use SETLOCAL to enable delayed expansion. Also you need to escape the ! character in a batch file whenever delayed expansion is enabled so that cmd.exe does not attempt to expand it. If enclosed within quotes then you can escape it simply as "^!". But if not within quotes then you must escape it as ^^^! Finally, if you are setting a variable to the new value, then you can enclose the entire expression in quotes and use the simpler escape sequence, yet the quotes won't be included in the value.

Code: Select all

@echo off
setlocal enableDelayedExpansion
set var=asdf
echo "!var:~0,1!OK^!!var:~2!"
echo !var:~0,1!OK^^^!!var:~2!
set "var=!var:~0,1!OK^^^!!var:~2!"
set var

Since your sample string does not contain any special characters, you don't need delayed expansion. In this case you don't need to escape the ! Note that I explicitly disabled delayed expansion, though normally it is the default state.

Code: Select all

@echo off
setlocal disableDelayedExpansion
set var=asdf
echo %var:~0,1%OK!%var:~2%
set var=%var:~0,1%OK!%var:~2%
set var


Dave Benham

Re: replace a substring by position

Posted: 01 Feb 2012 10:07
by Squashman
I think this is what you were actually trying to do.

Code: Select all

@echo off
setlocal enabledelayedexpansion
set var=asdfg
echo !var:%var:~1,1%=OK!

output

Code: Select all

E:\batch files\SET_example>example.bat
aOKdfg


EDIT: Dave Beat me!!!

Re: replace a substring by position

Posted: 01 Feb 2012 10:57
by dbenham
Ahh - but you figured out what atamo was attempting to do with the original syntax. I missed that. :)

However, if the 2nd character happens to appear in multiple locations, it will be replaced in all of them with your fixed version :!: I'm not sure if that is what is actually wanted. :?:


Dave Benham

Re: replace a substring by position

Posted: 01 Feb 2012 11:20
by atamo
thank's your fast help :oops:

Code: Select all

echo !var:%var:~1,1%=OK!  work nice that I want, get   aOKdfg



but in this case why !var:s=OK! don't expanded ?

Code: Select all

echo !var:!var:~1,1!=OK!    don't work, I get       !var:s=OK! 

Re: replace a substring by position

Posted: 01 Feb 2012 18:56
by Aacini
My SET/S macro do exactly what you need (and much more):
Aacini wrote:

Code: Select all

%SET/S% variable:~start,size=substring to insert

Previous "SET-Substring" macro replace part of the current "variable" value with another substring; the part to replace is given in the same way as the standard Batch substring extraction with the sole difference that it does not end at the last character by default, so this point must be explicitly indicated by -0 in "size".
For example:

Code: Select all

REM Insert the SET/S macro definition here...

set var=asdfg
%set/s% var:~1,1=OK
echo %var%
Result wrote:aOKdfg
You must note that your original code does NOT replace by position, but replaces all instances of the s letter in the string by the word OK.