Я был бы полезен, если бы вы включили ссылку на что-то, что объясняет технику, которую вы пытаетесь использовать. К счастью, я знаком с техникой.
Вы пытаетесь использовать расширение / переменную find / replace, чтобы вставить комментарий в строку, чтобы вы могли извлечь начало строки, вплоть до некоторой подстроки. Я более знаком с использованием REM
, но использование a :
label в качестве псевдо-комментария также должно работать.
Я покажу быстрый пример того, как это может работать. У меня есть ECHO ON
на стратегических линиях, чтобы вы могли видеть, как работает замена. Это требует, чтобы я использовал REM
вместо :
потому что метки не ECHOed.
@echo off
setlocal
set "var=String Before<split here>String After"
echo on
set "Before=%var:<split here>="&rem %
@set before
set "After=%var:*<split here>=%"
@set after
--ВЫХОД--
C:\test>set "Before=String Before" & rem String After
Before=String Before
C:\test>set "After=String After"
After=String After
Лишние пробелы вокруг &
являются артефактом того, как cmd.exe повторяет строку, на самом деле они не вводятся при поиске / замене. Но вы должны увидеть, как работает техника.
Я не понимаю, почему вы включили запятые и кавычки в строку поиска - их нет в вашей стартовой строке, поэтому ничего не будет заменено.
Важно использовать кавычки при сохранении начального значения %~1
чтобы защитить от ядовитых символов.
Наконец, также важно иметь кавычки в ваших последующих заданиях. Первая кавычка перед именем переменной, а закрывающая кавычка вводится термином замены, непосредственно перед &:
Поскольку вы используете :
вместо REM
, нет необходимости вводить пробел после :
Вот рабочий код. Обратите внимание, что я исключил необходимость в дополнительной переменной var
, используя Back
для временных значений, пока не буду готов получить окончательное значение Back.
@echo off
setlocal
call :extract "Hello there this is a block: [C]Inside of Block[/C] Did you like it?"
echo Front = "%Front%"
echo Inside = "%Inside%"
echo Back = "%Back%"
exit /b
:extract
set "Back=%~1"
set "Front=%Back:[C]="&:%
set "Back=%Back:*[C]=%"
set "Inside=%Back:[/C]="&:%
set "Back=%Back:*[/C]=%"
exit /b
-- ВЫХОД --
Front = "Hello there this is a block: "
Inside = "Inside of Block"
Back = " Did you like it?"
Обратите внимание на мое использование кавычек в выходных данных - они не находятся в фактических сохраненных значениях. Скорее они вводятся командой ECHO, чтобы показать существование конечного / ведущего пробела, а также защищают от ядовитых персонажей.
Вышеуказанная техника имеет несколько ограничений:
- Значение
%~1
не должно содержать кавычек, в противном случае вы рискуете отравить символы, искажающие результат
- Значение
%~1
не может содержать перевод строки (0x0A) или возврат каретки (0x0D).
- Подстроки, которые вы заменяете (
[C]
и [/C]
в вашем случае) не должны начинаться с ~
, *
или %
.
- Подстроки, которые вы заменяете, не должны содержать
=
где-либо внутри них
Вот совершенно не связанное решение JREPL.BAT
Если вам нравится работать с регулярными выражениями, то вы можете использовать мой JREPL.BAT - чистую утилиту сценариев (гибридный JScript/batch), которая работает на любом компьютере с Windows начиная с XP и не требует никаких сторонних .exe-файлов.
Решение JREPL будет немного медленнее, чем чистый пакет для этого приложения, но оно имеет два больших преимущества:
- Логика более прямолинейна, если вы понимаете регулярные выражения
- Там нет ограничений персонажа.
%~1
прежнему не может содержать возврат каретки или перевод строки. Но переменная может, и JREPL будет отлично работать с этими символами.
Если вам нужно извлечь только одно значение, тогда решение действительно простое - JREPL имеет возможность сохранить результат в переменной среды. Код ниже захватит значение внутри вашего блока:
@echo off
setlocal
call :extract "Hello there this is a block: [C]Inside of Block[/C] Did you like it?"
echo Inside = "%Inside%"
exit /b
:extract
set "Inside=%~1"
call jrepl "\[C](.*)\[/C]" "$txt=$1" /s Inside /jmatchq /rtn Inside
exit /b
-- ВЫХОД --
Inside = "Inside of Block"
Но вы хотите захватить 3 значения. Вы можете сделать три отдельных вызова JREPL, но это будет неэффективно. В приведенном ниже коде я вставляю VariableName=
и символы новой строки в соответствующие места, и позволяю FOR /F
повторять и сохранять три результата.
@echo off
setlocal
call :extract "Hello there this is a block: [C]Inside of Block[/C] Did you like it?"
echo Front = "%Front%"
echo Inside = "%Inside%"
echo Back = "%Back%"
exit /b
:extract
set "Front=%~1"
for /f "delims=" %%A in (
'jrepl "^|\[C]|\[/C]" "Front=|\nInside=|\nBack=" /s Front /t "|" /xseq'
) do set "%%A"
exit /b
-- ВЫХОД --
Front = "Hello there this is a block: "
Inside = "Inside of Block"
Back = " Did you like it?"
Обширная справка встроена в утилиту JREPL.
JREPL /?
перечислю всю помощь.
JREPL /?options
будут кратко обобщать все доступные варианты
JREPL /?/T
опишет опцию T ranslate, которую я использовал. Вы можете сделать то же самое для /?/XSEQ
и /?/S
Скорее всего, вы найдете множество вариантов использования JREPL, когда они появятся в вашем арсенале инструментов. JREPL действительно великолепен, когда дело доходит до манипулирования текстовыми файлами - он намного быстрее и мощнее, чем любое чистое пакетное решение.