Разделение строки с использованием CMD - PullRequest
0 голосов
/ 03 марта 2020

Я пишу небольшую программу и мне нужно разбить строку с указанными c значениями внутри.

Я пробовал несколько разных способов, но пришел с пустыми руками.

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

используя CMD, как бы вернуть только символы между [IDNUM] и [SNUM], чтобы отобразить «123456»?

Спасибо

Ответы [ 4 ]

2 голосов
/ 03 марта 2020

Я предполагаю, что ваша строка находится в переменной - я назову ее string, а вы хотите поместить значение в переменную val.

Если первый и второй [теги] всегда такие же, как у вас в вашем примере, и нет возможности других [ или ] до [SNUM], то

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

Ведущий X добавляется для обеспечения извлечения правильного значения независимо от того, содержит ли строка какие-либо символы перед [idnum].

Если вышеуказанное невозможно использовать, поскольку строка не имеет фиксированного формата, тогда можно использовать следующее при условии, что

  • значение не содержит нечетное количество кавычек
  • нет никаких ядовитых символов между кавычками в исходной строке.
  • можно игнорировать регистр при идентификации [тегов]
    set "val=%string:*[idnum]=%"
    set "val=%val:[snum]="&rem %

Первый set становится set "val=123456[SNUM]00001[DATEC]01012020[END]"

Второй set становится set "val=123456"&rem 00001[DATEC]01012020[END]

Должно быть очевидно, как это дает правильное значение.

Наконец, вот надежное решение, которое всегда должно работать, пока вы не столкнетесь с проблемами максимальной длины строки, и теги [ ] не чувствительны к регистру.

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=\!"

Если вы знаете, что строка никогда не может содержать | (или какой-либо другой символ), то это намного проще:

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"
)
2 голосов
/ 03 марта 2020

Подход короче / проще (2 строки):

@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%
0 голосов
/ 04 марта 2020

Еще один способ сделать это с помощью регулярного выражения.

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%
0 голосов
/ 03 марта 2020

Решение для командного файла

@echo off

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

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

pause

при смене токенов на 2 вы получите 123456, 4 - 00001 ....

...