Mam zmienną ( %~1
) ustawioną na coś takiego:Hello there this is a block: [C]Inside of Block[/C] Did you like it?
Chcę go podzielić na trzy zmienne:
Front=hello there this is a block:
Block=Inside of Block
Back=Did you like it?
Próbowałem użyć tego:
:call
set var=%~1
set Front=%var:,"[C]"=&:%
set Back=%var:*"[/C]=%
Set var=%var:,"[/C]"=&:%
Set var=%var:*"[C]=%
set Inside=%var%
Ale to nie działa. Może być tak, ponieważ jest to call
sekcja wywoływana z wnętrza for
pętli (z EnableDelayedExpansion). Ale cały ciąg jest ustawiony na każdą zmienną. Czy to się da zrobić?
windows-10
batch-file
text-editing
extract
string
Mark Deven
źródło
źródło
poisenous
takich znaków<>|&
, będziesz musiał zawrzeć cały zestaw par var = wartość w podwójnych cudzysłowach ->Set "Front=%var:,"[C]"=&:%"
(nie wiem, do czego służą wewnętrzne podwójne cudzysłowy).%
je zastąpić!
var
otrzymujesz pożądaną wartość%~1
? Jakie wartości przynoszą inne zadania? (echo
Oświadczenie jest twoim przyjacielem.) W związku z tym, jakich wartości oczekujesz od zadań? Też ich nie rozumiem; wyjaśnij logikę swojego kodu. … (Ciąg dalszy)Odpowiedzi:
Byłbym pomocny, gdybyś zamieścił link do czegoś, co wyjaśnia technikę, której próbujesz użyć. Na szczęście znam tę technikę.
Próbujesz użyć rozwinięcia zmiennej find / replace, aby wstawić komentarz do łańcucha, abyś mógł wyodrębnić początek łańcucha, aż do jakiegoś podłańcucha. Jestem bardziej zaznajomiony z używaniem
REM
, ale twoje użycie:
etykiety jako pseudo komentarza również powinno działać.Pokażę szybki przykład, jak to może działać. Mam
ECHO ON
na liniach strategicznych, abyś mógł zobaczyć, jak działa podstawienie. Wymaga to użyciaREM
zamiast,:
ponieważ etykiety nie są ECHOed.--WYDAJNOŚĆ--
Dodatkowe spacje wokół
&
są artefaktem tego, jak cmd.exe echa linii, tak naprawdę nie są wprowadzane przez find / replace. Ale powinieneś być w stanie zobaczyć, jak działa ta technika.Nie rozumiem, dlaczego umieściłeś przecinki i cytaty w ciągu wyszukiwania - nie ma ich w ciągu początkowym, więc nic nie zostanie zastąpione.
Ważne jest, aby używać cudzysłowów podczas zapisywania wartości początkowej,
%~1
aby zabezpieczyć się przed zatrutymi postaciami.Wreszcie kluczowe znaczenie mają cytaty w kolejnych zadaniach. Pierwszy cytat znajduje się przed nazwą zmiennej, a cytat zamykający jest wprowadzany przez termin zastępujący, tuż przed
&:
.Ponieważ używasz
:
zamiastREM
, nie ma potrzeby wprowadzania spacji po:
.Oto działający kod. Zauważ, że wyeliminowałem potrzebę dodatkowej
var
zmiennej, używającBack
wartości tymczasowych, dopóki nie będę gotowy, aby uzyskać ostateczną wartość Wstecz.- WYDAJNOŚĆ -
Zwróć uwagę na moje użycie cudzysłowów w danych wyjściowych - nie są one w rzeczywistych zapisanych wartościach. Są one raczej wprowadzane przez komendę ECHO, aby pokazać istnienie spływu / wiodącej przestrzeni, a także chroniłyby przed zatrutymi postaciami.
Powyższa technika ma kilka ograniczeń:
%~1
Wartość nie powinna zawierać żadnych cytatów, inaczej ryzykujesz znaków zatruć zgorszenie wynik%~1
Wartość ta może zawierać linia (0x0A) lub powrotu karetki (0x0d).[C]
i[/C]
w danym przypadku) nie musi zaczynać się~
,*
lub%
.=
nigdzie w nichOto całkowicie niepowiązane rozwiązanie JREPL.BAT
Jeśli lubisz pracować z wyrażeniami regularnymi, możesz użyć mojego JREPL.BAT - czystego narzędzia skryptowego (hybrydowy JScript / partia), które działa natywnie na dowolnym komputerze z systemem Windows od XP, nie potrzebujesz żadnego pliku .exe innej firmy.
Rozwiązanie JREPL będzie nieco wolniejsze niż czysta partia dla tej aplikacji, ale ma dwie duże zalety:
%~1
nadal nie może zawierać powrotu karetki ani podawania wiersza. Ale zmienna może i JREPL będzie działać dobrze z tymi znakami.Jeśli potrzebujesz tylko wyodrębnić jedną wartość, rozwiązanie jest naprawdę proste - JREPL ma możliwość przechowywania wyniku w zmiennej środowiskowej. Poniższy kod uchwyci wartość wewnątrz twojego bloku:
- WYDAJNOŚĆ -
Ale chcesz uchwycić 3 wartości. Możesz wykonać trzy osobne wywołania JREPL, ale byłoby to nieefektywne. W poniższym kodzie wstawiam
VariableName=
i nowe wiersze w odpowiednich miejscach oraz pozwalamFOR /F
iterować i przechowywać trzy wyniki.- WYDAJNOŚĆ -
Obszerna pomoc jest wbudowana w narzędzie JREPL.
JREPL /?
wyświetli całą pomoc.JREPL /?options
krótko podsumuje wszystkie dostępne opcjeJREPL /?/T
opisze T opcję ranslate że użyłem. Możesz zrobić to samo dla/?/XSEQ
i/?/S
Prawdopodobnie znajdziesz wiele zastosowań JREPL, gdy już znajdziesz je w swoim arsenale narzędzi. JREPL naprawdę błyszczy, gdy chodzi o manipulowanie plikami tekstowymi - jest o wiele szybszy i potężniejszy niż każde czyste rozwiązanie wsadowe.
źródło
Zasadniczo pliki wsadowe nie są bardzo wydajne w przetwarzaniu takich skomplikowanych rzeczy. Nie jest również możliwe użycie zamiany zmiennych tak, jak próbowałeś.
To powiedziawszy, to rozwiązanie powinno działać dla wszystkich ciągów zawierających pojedynczy blok lub nie zawierających żadnych bloków. To nie zadziała dla wielu bloków. Będzie również działać tylko dla pojedynczego znaku znaczników blokowych (czyli
[C]
,[b]
,[9]
). To również nie zadziała, jeśli masz[
w tekście znaki, które nie są częścią bloków.Split
Połączenie zostanie podzielona przez ciąg[
znaków i przekazać doSet
rozmowy.Set
Połączenie zostanie następnie usunąć znaczniki początku i końca bloku.Dalsza lektura: Zmienna edycja / zamiana - SS64
źródło