Page 3 of 3

Re: split string into substrings based on delimiter

Posted: 23 Dec 2017 13:33
by thefeduke
I have modified my last post that contained code with comments to correct the negative return code and to point out a restriction in using overlapping search strings.
John A.

Re: split string into substrings based on delimiter

Posted: 19 Feb 2018 15:25
by Aacini
I developed a new method that allows to use this technique to split two variables in the same replacement line, although it uses a trick in order to avoid the REM command that is usually used for this purpose, but that can not work in this case. The trick can also be used to split more than two variables.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "str=1.0.2.25"
set "vars=Major Minor Revision Subrev"

set "p=%%"
set "v=%vars: =" & set "s=!str:*.=!" & call set "!v!=!p!str:.!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!=!s!"

echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
Antonio

Re: split string into substrings based on delimiter

Posted: 19 Feb 2018 16:33
by jeb
Hi Aacini,

really nice :!: :D
It takes a minute to understand your code :idea:

Once upon a time, someone told me, that it's nice to explain a bit more and ever after I tried hard. :D

I suppose for some readers it would be helpful, when you show your idea.

jeb

Re: split string into substrings based on delimiter

Posted: 25 Feb 2018 20:50
by IcarusLives
Aacini wrote:
19 Feb 2018 15:25
I developed a new method that allows to use this technique to split two variables in the same replacement line, although it uses a trick in order to avoid the REM command that is usually used for this purpose, but that can not work in this case. The trick can also be used to split more than two variables.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "str=1.0.2.25"
set "vars=Major Minor Revision Subrev"

set "p=%%"
set "v=%vars: =" & set "s=!str:*.=!" & call set "!v!=!p!str:.!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!=!s!"

echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
Antonio
Aacini,

I'm really interested in how this works, but I'm struggling to understand it. Can you please explain with some detail this method?

Re: split string into substrings based on delimiter

Posted: 26 Feb 2018 09:21
by Aacini
jeb wrote:
19 Feb 2018 16:33
Hi Aacini,

really nice :!: :D
It takes a minute to understand your code :idea:

Once upon a time, someone told me, that it's nice to explain a bit more and ever after I tried hard. :D

I suppose for some readers it would be helpful, when you show your idea.

jeb
IcarusLives wrote: I'm really interested in how this works, but I'm struggling to understand it. Can you please explain with some detail this method?

The purpose of the method is to split two strings in their parts. This can be easily done in two lines and then combine the parts in a third line:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

set "str=1.0.2.25"
set "vars=Major Minor Revision Subrev"

set "i=1" & set "s!i!=%str:.=" & set /A i+=1 & set "s!i!=%"
set "i=1" & set "v!i!=%vars: =" & set /A i+=1 & set "v!i!=%"
for /L %%i in (1,1,%i%) do set "!v%%i!=!s%%i!"

echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
In this way, the goal is to complete the same split in just one line. To do that, in each division of the first string we must "split" the second string, that is, perform the equivalent process: take the value before the first dot to assign it to the variable, and ignore the rest of values. A first attempt to ignore the rest of the values (after the first dot) is inserting a "REM" command in the usual way:

Code: Select all

set "p=%%"
set "v=%vars: =" & call set "!v!=!p!str:.=& rem !p!" & set "str=!str:*.=!" & set "v=%" & set "!v!=!s!"
                   ^^^^          \________________/
The purpose of the marked part is to insert a REM command in place of the dots in the value of STR variable. However, this method have two problems: it is necessary to escape several special characters in this part in order to correctly execute the REM command, otherwise it is just assigned to the !V! variable. Anyway, when the REM command is successfully executed, it causes to ignore all commands after it, including the rest of commands that should split the rest of parts in the first string.

A workaround to do the same process without using a REM command is simple: first, take the rest of values after the first dot: set "s=!str:*.=!"; then, eliminate such a part from the variable (this gives just the first part): call set "!v!=!p!str:.!s!=!p!". Finally, assign the rest of values to the same variable (in preparation for the next part): set "str=!s!".

Code: Select all

set "v=%vars: =" & set "s=!str:*.=!" & call set "!v!=!p!str:.!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!=!s!"
Note that three previous steps are performed in each part of the split of first variable, that is, they are placed inside the only percent-signs in the line. At end, the last values remains in their respective variables but have not been processed, so an additional set "!v!=!s!" is inserted at end of line...

As jeb would say: it's obvious! 8)

Antonio

Re: split string into substrings based on delimiter

Posted: 28 Feb 2018 11:49
by IcarusLives
OOOOHHH Okay now I can see it. Thank you so much for the great explanation!

Re: split string into substrings based on delimiter

Posted: 19 Aug 2018 10:25
by Aacini
I have extended the last method I posted here in order to easily split a string in several parts specified by the length of each one:

Code: Select all

@echo off
setlocal EnableDelayedExpansion


call :Split "10225" "Major:1 Minor:1 Revision:1 Subrev:2"
rem The result should be Major:1, Minor:0, Revision:2, Subrev:25
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%


for /F "tokens=2 delims==" %%t in ('wmic os get localdatetime /value') do set "dateTime=%%t"
echo/
echo DateTime: %dateTime%
call :Split "%dateTime%" "Year:4 Month:2 Day:2 Hour:2 Minute:2 Second:2 _:7 Offset:4"
echo Year:%Year%  Month:%Month%  Day:%Day%  Hour:%Hour%  Minute:%Minute%  Second:%Second%  Offset:%Offset%

goto :EOF



:Split string "var1:len1 var2:len2 ..."
set "str=%~1" & set "vars=%~2 " & set "p=%%"
set "v=%vars: =" & set "len=!v:*:=!" & call set "name=!p!v::!len!=!p!" & call set "!name!=!p!str:~0,!len!!p!" & call set "str=!p!str:~!len!!p!" & set "v=%"
exit /B
Output:

Code: Select all

Major: 1, Minor: 0, Revision: 2, Subrev: 25

DateTime: 20180819111956.885000-300
Year:2018  Month:08  Day:19  Hour:11  Minute:19  Second:56  Offset:-300
The method is exactly the same than the last explained one, so no further explanations here... :roll:

Antonio

Re: split string into substrings based on delimiter

Posted: 19 Aug 2018 13:07
by aGerman
That's neat. Thanks for sharing, Antonio!

Steffen