Как перебрать токены в строке? - PullRequest
15 голосов
/ 13 декабря 2011

Скажем, у меня есть строка, такая как foo: bar: baz, возможно ли перебрать эту строку? Выглядело так, как будто вы можете разбить строки файла на части, но следующее будет выводить 'foo' только один раз.

for /f "tokens=1,2* delims=:" %%x in ("%%j") do echo %%x

Ответы [ 4 ]

19 голосов
/ 13 декабря 2011
set string=foo:bar:baz
for %%x in (%string::= %) do echo %%x

FOR разделителями значений могут быть пробел, запятая, точка с запятой и знак равенства.Вы можете напрямую обработать строку, если элементы разделены любым из этих символов.Если нет, просто измените разделитель для одного из этих символов (как я делал выше).

set string=foo bar,baz;one=two
for %%x in (%string%) do echo %%x
9 голосов
/ 13 декабря 2011

Аасини побил меня своим первым решением. Его можно улучшить, добавив кавычки, чтобы строка могла содержать пробелы и специальные символы и при этом давать правильный результат.

set "str=foo bar:biz bang:this & that"
for %%S in ("%str::=" "%") do echo %%~S

Решение имеет ограничения:

  • Нет * или? может появиться в строке
  • Проблемы могут возникнуть, если строка уже содержит кавычки ("), особенно если есть специальные символы

Второе решение имеет причудливый синтаксис, но концепция довольно проста. FOR / F со строкой будет разбивать символы перевода строки - каждая строка будет обрабатываться как отдельная строка. Хитрость заключается в замене разделителя : символом перевода строки. Обратите внимание, что пустая строка в приведенном ниже решении является важной частью сложной замены. Кроме того, следующая строка должна начинаться с !, который завершает расширение отложенной переменной. Не должно быть пробелов.

Другая вещь, о которой стоит беспокоиться, это противная опция FOR / F "EOL". Мы не хотим пропускать значения, начинающиеся с символа EOL, который по умолчанию равен ;. Поскольку мы исключили разделитель строк :, мы можем смело использовать его в качестве EOL.

Наконец, нам нужно использовать отложенное расширение, но ! будет повреждено при расширении %% S, если мы сначала не отключим отложенное расширение в цикле.

set "str=foo bar:biz bang:this & that "^& the other thing!":;How does this work?"
setlocal enableDelayedExpansion
set ^"str=!str::=^

!"
for /f "eol=: delims=" %%S in ("!str!") do (
  if "!!"=="" endlocal
  echo %%S
)

Я полагаю, что эта техника может справиться практически со всем, что вы на нее бросаете.

Джеб первым показал мне, как работать с переводами строк внутри пакета, и особенно, как использовать эту технику. Это может быть даже опубликовано где-то еще на SO.

2 голосов
/ 13 декабря 2011

он делает как положено, он маркирует его на %%x %%y %%z. Так что вместо обработки %%x вы можете ...

for /f "tokens=* delims=:" %%x in ("foo:bar:baz") do (
  echo %%x
  echo %%y
  echo %%z
)

или, если вы не знаете заранее, сколько предметов вы получили, вы можете ...

@echo off
set string=foo:bar:baz
:again
for /f "tokens=1* delims=:" %%x in ("%string%") do (
   echo %%x 
   set string=%%y
)
if not .%string%==. goto again
echo done
1 голос
/ 14 декабря 2011

Это будет анализировать строку в переменные, доступные вне цикла (;

setlocal enabledelayedexpansion

set your_string="whatever:you:want"

for /f "tokens=1,2,3 delims=:" %%a in ('echo !your_string!') do (
    set first_sub_string=%%a
    set second_sub_string=%%b
    set third_sub_string=%%c
)

echo Congrats.  !your_string! was parsed as !first_sub_string!, !second_sub_string!, !third_sub_string!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...