Eu teria sido útil se você tivesse incluído um link para algo que explica a técnica que você está tentando usar. Felizmente, estou familiarizado com a técnica.
Você está tentando usar a localização / substituição de expansão de variável para injetar um comentário em uma sequência de caracteres para que você possa extrair o início da cadeia, até uma subseqüência de caracteres. Estou mais familiarizado com o uso de REM
, mas o uso de um rótulo :
como um pseudo comentário também deve funcionar.
Mostrarei um exemplo rápido de como isso pode funcionar. Eu tenho ECHO ON
em linhas estratégicas para que você possa ver como a substituição funciona. Isso requer que eu use REM
em vez de :
porque os rótulos não são ECO.
@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
- OUTPUT -
C:\test>set "Before=String Before" & rem String After
Before=String Before
C:\test>set "After=String After"
After=String After
Os espaços extras ao redor do &
são um artefato de como o cmd.exe ecoa a linha, eles não são realmente introduzidos pelo localizar / substituir. Mas você deve ser capaz de ver como a técnica funciona.
Eu não entendo por que você incluiu vírgulas e citações em sua string de pesquisa - elas não estão lá na sua string inicial, então nada será substituído.
É importante que você use aspas ao salvar o valor inicial de %~1
para proteger contra caracteres suspeitos.
Finalmente, também é importante ter cotações em suas atribuições subsequentes. A primeira cotação é anterior ao nome da variável, e a cotação de fechamento é injetada pelo termo de substituição, logo antes do &:
.
Como você está usando :
em vez de REM
, não é necessário introduzir um espaço após o :
.
Aqui está o código de trabalho. Observe que eliminei a necessidade de uma variável var
extra usando Back
para os valores temporários até que eu esteja pronto para obter o valor final de 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
- OUTPUT -
Front = "Hello there this is a block: "
Inside = "Inside of Block"
Back = " Did you like it?"
Observe meu uso de aspas na saída - elas não estão nos valores reais armazenados. Em vez disso, eles são introduzidos pelo comando ECHO para mostrar a existência do espaço à esquerda / líder, e também protegem contra caracteres envenenados.
A técnica acima tem algumas restrições:
- O valor
%~1
não deve conter aspas, senão você corre o risco de caracteres envenenados que corrompem o resultado - O valor
%~1
não pode conter nova linha (0x0A) nem retorno de carro (0x0D). - As subseqüências que você está substituindo (
[C]
e[/C]
no seu caso) não devem começar com~
,*
ou%
. - As subseqüências que você está substituindo não devem conter
=
em qualquer lugar dentro delas
Aqui está uma solução JREPL.BAT totalmente não relacionada
Se você gosta de trabalhar com expressões regulares, pode usar meu JREPL.BAT - um utilitário de script puro (JScript / batch híbrido) executado nativamente em qualquer máquina Windows do XP em diante, sem necessidade de nenhum arquivo .exe de terceiros.
A solução JREPL será um pouco mais lenta que o lote puro para esta aplicação, mas tem duas grandes vantagens:
- A lógica é mais direta, desde que você entenda expressões regulares
- Não há limites de caracteres.
%~1
ainda não pode conter retorno de carro ou alimentação de linha. Mas uma variável pode, e o JREPL funcionará bem com esses caracteres.
Se você só precisa extrair um único valor, a solução é realmente simples - o JREPL tem a capacidade de armazenar o resultado em uma variável de ambiente. O código abaixo irá capturar o valor dentro do seu bloco:
@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
- OUTPUT -
Inside = "Inside of Block"
Mas você quer capturar 3 valores. Você poderia fazer três chamadas JREPL separadas, mas isso seria ineficiente. No código abaixo eu insiro VariableName=
e newlines nos locais apropriados e deixo FOR /F
iterar e armazenar os três resultados.
@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
- OUTPUT -
Front = "Hello there this is a block: "
Inside = "Inside of Block"
Back = " Did you like it?"
Extensa ajuda está embutida no utilitário JREPL.
-
JREPL /?
listará toda a ajuda. -
JREPL /?options
resumirá brevemente todas as opções disponíveis -
JREPL /?/T
descreverá a opção de conversão T que usei. Você pode fazer o mesmo para/?/XSEQ
e/?/S
Você provavelmente encontrará muitos usos para o JREPL, uma vez que o tenha em seu arsenal de ferramentas. O JREPL realmente brilha quando se trata de manipular arquivos de texto - é muito mais rápido e mais poderoso do que qualquer solução de lote puro.