0

I am writing a little program and need to split a string with specific values inside.

I have tried multiple different ways but come up empty handed.

[IDNUM]123456[SNUM]00001[DATEC]01012020[END]

using CMD how would i return just the characters between [IDNUM] and [SNUM] to show "123456" ?

Thank you

2
  • At the command prompt, FOR /F "tokens=3 delims=[]" %A IN ("str=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]") DO @ECHO %A. In a batch file, use %%A instead of %A. Commented Mar 3, 2020 at 15:27
  • Perfect, Thank you. set "str=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]" FOR /F "tokens=2 delims=[]" %%A IN ("%str%") DO @ECHO %%A Commented Mar 3, 2020 at 15:33

4 Answers 4

2

I'll assume your string is in a variable - I'll call it string, and you want to put the value in variable val.

If the first and second [tags] are always as you have in your example, and no possibility of other [ or ] before [SNUM], then

for /f "delims=[] tokens=3" %%A in ("X%string%") do set "val=%A"

The leading X is added to ensure the correct value is extracted regardless whether the string includes any characters before [idnum].

If the above can't be used because the string does not have a fixed format, then the following can be used provided that

  • the value does not contain an odd number of quotes
  • there are no poison characters between quotes within the original string.
  • it is safe to ignore case when identifying [tags]
    set "val=%string:*[idnum]=%"
    set "val=%val:[snum]="&rem %

The first set becomes set "val=123456[SNUM]00001[DATEC]01012020[END]"

The second set becomes set "val=123456"&rem 00001[DATEC]01012020[END]

It should be obvious how that gives the correct value.

Lastly, here is a robust solution that should always work as long as you don't run into maximum string length issues, and the [tags] are not case sensitive.

setlocal disableDelayedExpansion
setlocal enableDelayedExpansion

:: escape \ and | characters
set "val=!string:\=\S!"
set "val=!val:|=\P!"

:: convert [idnum] and [snum] to |
set "val=!val:[idnum]=|!"
set "val=!val:[snum]=|!"

:: parse out the value. delayed expansion is toggled off so it does not corrupt any `!` that might appear within the value
for /f "tokens=2 delims=|" %%A in ("X!val!") do (
  endlocal
  set "val=%%A"
)

:: restore any \ and |
setlocal enableDelayedExpansion
set "val=!val:\P=|!"
set "val=!val:\S=\!"

If you know that the string can never contain | (or some other character), then it is much simpler:

setlocal disableDelayedExpansion
setlocal enableDelayedExpansion
set "val=!string:[idnum]=|!"
set "val=!string:[snum]=|!"
for /f "tokens=2 delims=|" %%A in ("X!val!") do (
  endlocal
  set "val=%%A"
)
Sign up to request clarification or add additional context in comments.

2 Comments

little edit on the code worked for me set "string=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]" set "val=%string:*[idnum]=%" set "val=%val:[snum]="%, perfect
@LDowling - Yes, you can simply substitute " for [snum] if and only if there are no quotes after [snum]. Everything after the last " is ignored. My original answer was missing a space after the rem, I fixed that error in an edit.
2

A shorter/simpler (2 lines) approach:

@echo off
setlocal

set "string=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]"

rem Replace ']' by '=' giving [IDNUM=123456[SNUM=00001[DATEC=01012020[END=
set "string=%string:]==%"

rem Replace '[' by '" & set "' giving " & set "IDNUM=123456" & set "SNUM=00001" & set "DATEC=01012020" & set "END=
rem and *execute* such a line inserting a 'set "X=' correction before the first '" &'
rem                           and a quote after the last '='

set "X=%string:[=" & set "%"

rem After this line each one of the variables have their corresponding values
echo IDNUM=%IDNUM%

2 Comments

Very nice. I didn't look at the line format that closely, or stop to consider that the OP might want multiple values. Of course this will clear any existing X value. You might want to change X to some variable name that should never be defined, like CD or ERRORLEVEL, although that would look mighty strange. Or you could use 2>nul set "=%string:[=" & set "%"
@dbenham: the usual method to perform this multiple sustitution would use the same working variable: set "string=%string:[=" & set "%"
0

Solution for a batch file

@echo off

set "str=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]"

FOR /F "tokens=2 delims=[]" %%A IN ("%str%") DO @ECHO %%A

pause

when changing tokens to 2 you will get 123456, 4 you will get 00001 ....

2 Comments

well after running my script the above is correct but your answer is better for my needs. thank you @dbenham
I misunderstood your intent in your question. I thought str= was part of the string. Down vote removed.
0

One more way to do it with a regex.

SET "S=[IDNUM]123456[SNUM]00001[DATEC]01012020[END]"
FOR /F "delims=" %%A IN ('powershell -NoLogo -NoProfile -Command ^
    "$null = '%S%' -match '.*\[IDNUM\](.*?)\[.*'; $Matches[1]"') DO (SET "RESULT=%%A")
ECHO RESULT is %RESULT%

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.