split string into substrings based on delimiter
Moderator: DosItHelp
Re: split string into substrings based on delimiter
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.
John A.
Re: split string into substrings based on delimiter
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.
Antonio
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%
Re: split string into substrings based on delimiter
Hi Aacini,
really nice
It takes a minute to understand your code
Once upon a time, someone told me, that it's nice to explain a bit more and ever after I tried hard.
I suppose for some readers it would be helpful, when you show your idea.
jeb
really nice
It takes a minute to understand your code
Once upon a time, someone told me, that it's nice to explain a bit more and ever after I tried hard.
I suppose for some readers it would be helpful, when you show your idea.
jeb
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: split string into substrings based on delimiter
Aacini,Aacini wrote: ↑19 Feb 2018 15:25I 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.
AntonioCode: 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%
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
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%
Code: Select all
set "p=%%"
set "v=%vars: =" & call set "!v!=!p!str:.=& rem !p!" & set "str=!str:*.=!" & set "v=%" & set "!v!=!s!"
^^^^ \________________/
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!"
As jeb would say: it's obvious!
Antonio
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: split string into substrings based on delimiter
OOOOHHH Okay now I can see it. Thank you so much for the great explanation!
Re: split string into substrings based on delimiter
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:
Output:
The method is exactly the same than the last explained one, so no further explanations here...
Antonio
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
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
Antonio
Re: split string into substrings based on delimiter
That's neat. Thanks for sharing, Antonio!
Steffen
Steffen
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Efficient Array Management Operations in Batch files
This magic line
I did not expect this resulted behavior. Quiet astounding! I imagine this method is much faster compared to intuitive loops.
I'm always so overwhelmed with excitement with releases like this.
As always, GREAT WORK!
Code: Select all
set "i=1" & set "s!i!=%str:.=" & set /A i+=1 & set "s!i!=%"
I'm always so overwhelmed with excitement with releases like this.
As always, GREAT WORK!
Last edited by aGerman on 18 Oct 2021 12:56, edited 1 time in total.
Reason: This, and the following two posts have been moved from https://www.dostips.com/forum/viewtopic.php?f=3&t=10214
Reason: This, and the following two posts have been moved from https://www.dostips.com/forum/viewtopic.php?f=3&t=10214
Re: Efficient Array Management Operations in Batch files
Yep this was discussed about 6 years ago in this thread.IcarusLives wrote: ↑23 Sep 2021 15:50This magic line
I did not expect this resulted behavior. Quiet astounding! I imagine this method is much faster compared to intuitive loops.Code: Select all
set "i=1" & set "s!i!=%str:.=" & set /A i+=1 & set "s!i!=%"
I'm always so overwhelmed with excitement with releases like this.
As always, GREAT WORK!
viewtopic.php?f=3&t=6429
-
- Posts: 175
- Joined: 17 Jan 2016 23:55
Re: Efficient Array Management Operations in Batch files
That's exactly why it's so amazing. Because even after coding in batch for so many years, I'm STILL learning things. I just think that's really great, and that's why I love this site.Squashman wrote: ↑23 Sep 2021 15:59Yep this was discussed about 6 years ago in this thread.
viewtopic.php?f=3&t=6429
Re: split string into substrings based on delimiter
I used one of your concepts in this thread to answer a question on StackOverFlow. Then I was bored and figured why not make an array if there is more than one line of output.Aacini wrote: ↑19 Feb 2018 15:25I 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.
AntonioCode: 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%
Code: Select all
@echo off
setlocal enabledelayedexpansion
REM Get Driver Query Header Row to use has variables
for /f "delims=" %%G in ('driverquery /V /FO CSV') do (set "vars=%%~G" & GOTO NEXT)
:NEXT
REM Cleanup variable names
SET "vars=%vars: =_%"
SET "vars=%vars:(=_%"
SET "vars=%vars:)=%"
SET "vars=%vars:path=dPath%"
SET "vars=%vars:","= %"
REM
SET "count=0"
set "p=%%"
for /f "delims=" %%G in ('driverquery /V /FO CSV ^|findstr /IC:"Virtual WiFi"') do (
set /A "count+=1"
set "str=%%~G"
set "v=%vars: =" & set "s=!str:*","=!" & call set "!v!!count!=!p!str:","!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!!count!=!s!"
)
REM Display Driver Query Array
FOR /L %%C IN (1,1,%count%) DO FOR %%G IN (%vars%) DO SET %%G%%C
Code: Select all
Module_Name1=vwififlt
Display_Name1=Virtual WiFi Filter Driver
Description1=Virtual WiFi Filter Driver
Driver_Type1=Kernel
Start_Mode1=System
State1=Running
Status1=OK
Accept_Stop1=TRUE
Accept_Pause1=FALSE
Paged_Pool_bytes1=4,096
Code_bytes1=53,248
BSS_bytes1=0
Environment variable Link_Date1 not defined
dPath1=C:\WINDOWS\system32\drivers\vwififlt.sys
Init_bytes1=4,096
Module_Name2=vwifimp
Display_Name2=Virtual WiFi Miniport Service
Description2=Virtual WiFi Miniport Service
Driver_Type2=Kernel
Start_Mode2=Manual
State2=Running
Status2=OK
Accept_Stop2=TRUE
Accept_Pause2=FALSE
Paged_Pool_bytes2=4,096
Code_bytes2=32,768
BSS_bytes2=0
Environment variable Link_Date2 not defined
dPath2=C:\WINDOWS\system32\drivers\vwifimp.sys
Init_bytes2=4,096
Re: split string into substrings based on delimiter
I discovered a new simpler (and clearer) method to assign values to several variables in the same line. I think this is the simplest way to do it:
If the values are numeric, then the multiple assignments can be performed in an even simpler way via a SET /A command:
Antonio
Code: Select all
@echo off
setlocal EnableDelayedExpansion
set "str=1.0.2.25"
set "Major=%str:.=" & set "Minor=!Revision!" & set "Revision=!Subrev!" & set "Subrev=%"
echo Major: %Major%, Minor: %Minor%, Revision: %Revision%, Subrev: %Subrev%
Code: Select all
set /A "Major=%str:.=" & set /A "Minor=Revision,Revision=Subrev,Subrev=%"
Re: split string into substrings based on delimiter
True but not as dynamic. If I wanted to add another sub version all I have to do is edit the two variables.
Code: Select all
@echo off
setlocal EnableDelayedExpansion
set "str=1.0.2.25.69"
set "vars=Major Minor Revision Subrev Last"
set "p=%%"
set "v=%vars: =" & set "s=!str:*.=!" & call set "!v!=!p!str:.!s!=!p!" & set "str=!s!" & set "v=%" & set "!v!=!s!"
FOR %%G IN (%vars%) DO call set /p ".=%%G: %%%%G%%, "<nul
Re: split string into substrings based on delimiter
Although you are right, the last method is the simplest and purest way to write such a multiple assignment in Batch because it does not require any additional elements besides the variable names (unlike the previous method which has a lot of strange elements), making it easier for beginners to understand and use in Batch files. Anyway, if dynamic change is required, then the last method can also be used automatically through this modification:Squashman wrote: ↑22 Dec 2021 16:54True but not as dynamic. If I wanted to add another sub version all I have to do is edit the two variables.Code: Select all
. . .
Code: Select all
@echo off
setlocal EnableDelayedExpansion
set "str=1.0.2.25.69"
set "vars=Major Minor Revision Subrev Last "
set "$2=" & set "$3=" & set "$4="
set "$1=%vars: =" & (if not defined $3 set "$3=!$1!") & set "$4=!$4!,!$2!=!$3!" & set "$2=!$3!" & set "$3=%"
set "$4=!$4:*%$1%,=!,%$2%"
set "%$2%=%str:.=" & set /A "!$4!=%"
for %%G IN (%vars%) do set /P "=%%G: !%%G!, " < NUL