string manipulation, small version

Microsoft Windows
Post Reply
User avatar
MigrationUser
Posts: 336
Joined: 2021-Jul-12, 1:37 pm
Contact:

string manipulation, small version

Post by MigrationUser »

25 Nov 2008 15:51
sergiu14


How to extract all letters from a string, without using the long version... (extracting all letters one after the other, or using a function which loops through the alphabet)

Does a small version exists?
Something like : set x=%x:[a-z][A-Z]=% which doesn't work...

Thank you ;)

----------------------------

#2 25 Nov 2008 17:16
bluesxman


Nothing native directly equates to the command you're trying.

Does this count as the "long" version?

Code: Select all

@echo off
set "string.in=the:quick-brown)fox jumps:over-the(lazy dog;JACKDAWS-LOVE)MY BIG:SPHINX-OF$QUARTZ"
set "string.out=%string.in%"
set alpha=a b c d e f g h i j k l m n o p q r s t u v w x y z

for %%a in (%alpha%) do call set "string.out=%%string.out:%%a=%%"

set string

pause
Last edited by bluesxman (25 Nov 2008 17:17)

cmd | *sh | ruby | chef

----------------------------

#3 25 Nov 2008 23:53
sergiu14


bluesxman you rule :D

----------------------------

#4 26 Nov 2008 09:09
sergiu14


Hello bluesxman, you used : call set "string.out=%%string.out:%%a=%%", why do you use 2 pairs of %(what does it mean)? (%%string.out:%%a=%%) I see that it doesn't work with one pair of %.

----------------------------

#5 26 Nov 2008 12:25
bluesxman


I did that to avoid having to use "setlocal enabledelayedexpansion" -- as use of that can cause problems when you're working with strings containing the bang "!" character.

Check this post oldforum/viewtopic.php?id=541 and this help page https://ss64.com/nt/setlocal.html for a bit more information on the subject.

By using "call" I am causing it to expand the variable outside the context of the FOR loop. The first expansion reduces it to %string.out:<Current Letter as defined by %%a>=%. The second expansion replaces current letter that the FOR loop is providing with nothing.

It's a bit tricky to explain. Hope that's clear.

cmd | *sh | ruby | chef

----------------------------

#6 26 Nov 2008 17:03
sergiu14


I still don't understand the effect of the exterior pair of %
call set z=%%z:a=%%
%z:a=% (the value of z, without the letter a) so if z=abc ==> z=abc(that doesn't modify z), but the value of %z:a=% is bc
Now we got call set z=%bc% and from here.. DEAD END :D

----------------------------

#7 26 Nov 2008 17:04
sergiu14


dont tell me that is like for %%a variable, differs from a script to cmd line???

----------------------------

#8 26 Nov 2008 17:06
sergiu14


"for /f %%a in (blah blah) do" with "for /f %a in (blah blah) do" Is this the purpose for the exterior pair of % ?? thanks

----------------------------

#9 27 Nov 2008 14:36
bluesxman


The wrapping "%%" are reduced to single "%" in the first expansion. The string.out variable is still not expanded at this point, only the value of "%%a" is.

In the second expansion it expands string.out, replacing the value of %%a assigned in the first expansion with nothing.

Last edited by bluesxman (27 Nov 2008 14:37)

cmd | *sh | ruby | chef

----------------------------

#10 27 Nov 2008 15:22
sergiu14


First of all thanks, for your time.

"The wrapping "%%" are reduced to single "%" in the first expansion."

example :

set z=abc
for %x in (a b) do call set z=%%z:%x=%%

echo.%z% will output %%c%% . which means they are not reduced . What is happening here?

----------------------------

#11 28 Nov 2008 03:14
avery_larry


Here's what happens. When you execute a "call set <something>" command, the line is actually processed twice -- the first time for the call command, and then again for the set command. So for example:

Code: Select all

@echo off
set test=something
set test3=something_else
set fun=ing
set testing=something_neat

call :process 3 test
goto :eof

:process
call set first_test=%%test%fun%%%
echo %first_test%
call set second_test=%%test%1%%
echo %second_test%
call set third_test=%%%2%%
echo %third_test%
goto :eof
Here's what happens:

call set first_test=%%test%fun%%%
the call command will change all double %% into single %, and expands any normal looking variables. For the first pass, think of %%test%fun%%% in 4 separate parts (I'm adding spaces so you can see what's going on):

%% test %fun% %%

So the 2 double quotes are changed to single quotes, the variable is expanded, and the static text is carried over (still with spaces to show how the 4 parts are separately evaluated):

% test ing %

So putting it together, the FIRST pass (the call statement) leaves us with:

set first_test=%testing%

which, of course, is then evaluated as:

set first_test=something_neat

Similar for all the rest:

%%test%1%%

%% test %1 %%

% test 3 %
set second_test=%test3%
set second_test=something_else

%%%2%%

%% %2 %%

% test %

set third_test=%test%
set third_test=something

PS -- this is, I believe, exclusively a feature of "call set". Don't try to do this in a for loop or anything like that.

Last edited by avery_larry (28 Nov 2008 03:17)

----------------------------

#12 28 Nov 2008 10:58
bluesxman
sergiu14 wrote:

What is happening here?
You're not running it inside a script. Things work ever so slightly differently when you do that -- you don't have to escape the %. From the command line you'd have to do:

Code: Select all

set z=abc

for %x in (a b) do call set z=%z:%x=%
echo:%z%
cmd | *sh | ruby | chef

----------------------------

#13 28 Nov 2008 11:46
sergiu14


now I understand smile thank you guys

----------------------------

#14 28 Nov 2008 12:05
klint


I've just been thinking, sort of philosophically - usually a lot of rubbish comes out of my mind when I do that - about the need to escape % in a batch file, and wondered...

Q: As we know, ^ is the batch file's escape character. It's used in things like ^|, ^> and ^< to quote the literal character rather than carry out redirection. So why do we use %% instead of ^% ?

Any ideas?

----------------------------

#15 28 Nov 2008 12:35
bluesxman


Because "^%" doesn't work smile

As for why it doesn't work ... only Microsoft could answer that.

Here's another thinker: when using delayed expansion, how do you escape "!"?

cmd | *sh | ruby | chef

----------------------------

#16 28 Nov 2008 18:24
klint


You'd think it was "!!" wouldn't you? But no...

----------------------------

#17 03 Dec 2008 18:27
carlos
bluesxman wrote:

Because "^%" doesn't work smile

As for why it doesn't work ... only Microsoft could answer that.

Here's another thinker: when using delayed expansion, how do you escape "!"?
For escape ! using delayedexpansion:

^^!

Example:

Code: Select all

@echo off
setlocal enabledelayedexpansion

set word=hi
echo !word!
echo ^^!word^^!

pause
----------------------------

#18 04 Dec 2008 01:29
bluesxman


In the simplest examples as you state, that's fine. But as soon as you try to start doing anything beyond that, it becomes steadily more difficult... e.g.

Code: Select all

@echo off

setlocal enabledelayedexpansion

set someVar=this^^!that

set someVar

echo:Which is great, except when echoing it...

echo:%someVar%

pause
... Now try doing string replacements and such, that's a whole lotta fun.

You'll find that you keep enabling/disabling delayed expansion, substituting "!" with other characters and doing just about anything to avoid turning on delayed expansion in the first place. All of which can be a royal pain.

cmd | *sh | ruby | chef

----------------------------

#19 04 Dec 2008 06:57
carlos

Code: Select all

echo:%someVar:!=^^!%
----------------------------

#20 09 Dec 2008 00:48
avery_larry


But that's easy -- avoid ! in your variables. It's much easier than avoiding enabledelayedexpansion.

OK -- never mind. In my own personal world of usage, I've never once wanted or used a ! in a variable so I've never had problems using enabledelayedexpansion. It is, in fact, my default mode of operation.

Ted

----------------------------

#21 09 Dec 2008 00:49
avery_larry
carlos wrote:

echo:%someVar:!=^^!%

Code: Select all

if defined someVar echo.%someVar:!=^^!%
tongue

----------------------------

#22 18 Dec 2008 17:28
carlos

Code: Select all

echo !someVar!
Post Reply