web-dev-qa-db-fra.com

Fractionner une chaîne avec une chaîne comme séparateur

J'essaie de scinder une chaîne dans un fichier de commandes en utilisant une chaîne (plutôt qu'un caractère) comme délimiteur.

La chaîne a le format:

string1 by string2.txt

Le délimiteur est by (oui, espace, le mot 'par', suivi d'un espace). La sortie que je veux est:

string1

string2

Donc, en gros, divisez la chaîne en 2 parties par le délimiteur by et supprimez le suffixe de la deuxième chaîne. Comment puis-je faire ceci?

18
user1773179

Essaye ça:

for /F "tokens=1,3 delims=. " %%a in ("%string%") do (
   echo %%a
   echo %%b
)

c'est-à-dire, prenez les premier et troisième jetons délimités par un espace ou un point ...

35
Aacini

J'ai récemment découvert un truc intéressant qui permet de "scinder une chaîne avec une chaîne comme séparateur", je ne pouvais donc pas résister à la tentation de la poster ici en tant que nouvelle réponse. Notez que "évidemment, la question n’était pas précise. Premièrement, chaîne1 et chaîne2 peuvent contenir des espaces. Deuxièmement, chaîne1 et chaîne2 peuvent contenir des esperluettes ('&')". Cette méthode fonctionne correctement avec les nouvelles spécifications (posté comme commentaire sous la réponse de Stephan).

@echo off
setlocal

set "str=string1&with spaces by string2&with spaces.txt"

set "string1=%str: by =" & set "string2=%"
set "string2=%string2:.txt=%"

echo "%string1%"
echo "%string2%"

Pour plus de détails sur la méthode split, voir cet article .

10
Aacini
@ECHO OFF
SETLOCAL
SET "string=string1 by string2.txt"
SET "string=%string:* by =%"
ECHO +%string%+

GOTO :EOF

La commande SET ci-dessus supprimera les données indésirables. Résultat affiché entre + pour démontrer l'absence d'espaces.

Formule: set var =% somevar: * string1 = string2%

assignera à var la valeur de somevar avec tous les caractères jusqu’à string1 remplacés par string2. Les guillemets englobants dans une commande set garantissent que les espaces en fin de fuite sur la ligne ne sont pas inclus dans la valeur attribuée.

2
Magoo

J'ai développé la réponse de Magoos pour obtenir les deux chaînes souhaitées:

@ECHO OFF
SETLOCAL enabledelayedexpansion
SET "string=string1 by string2.txt"
SET "s2=%string:* by =%"
set "s1=!string: by %s2%=!"
set "s2=%s2:.txt=%"
ECHO +%s1%+%s2%+

EDIT: juste pour le prouver, ma solution fonctionne également avec les exigences supplémentaires:

@ECHO OFF
SETLOCAL enabledelayedexpansion
SET "string=string&1 more words by string&2 with spaces.txt"
SET "s2=%string:* by =%"
set "s1=!string: by %s2%=!"
set "s2=%s2:.txt=%"
ECHO "+%s1%+%s2%+"
set s1
set s2

Sortie:

"+string&1 more words+string&2 with spaces+"
s1=string&1 more words
s2=string&2 with spaces
1
Stephan

J'ai trouvé deux scripts plus anciens qui utilisent une chaîne indéfinie, voire une chaîne spécifique, pour se scinder . Comme approche, ils sont toujours utiles.

https://www.administrator.de/contentid/226533#comment-1059704https://www.administrator.de/contentid/267522#comment-1000886

@echo off
:noOption
if "%~1" neq "" goto :nohelp
echo Gibt eine Ausgabe bis zur angebenen Zeichenfolge&echo(
echo %~n0 ist mit Eingabeumleitung zu nutzen
echo %~n0 "Zeichenfolge" ^<Quelldatei [^>Zieldatei]&echo(
echo    Zeichenfolge    die zu suchende Zeichenfolge wird mit FIND bestimmt
echo            ohne AusgabeUmleitung Ausgabe im CMD Fenster
exit /b
:nohelp
setlocal disabledelayedexpansion
set "intemp=%temp%%time::=%"
set "string=%~1"
set "stringlength=0"
:Laenge string bestimmen
for /f eol^=^

^ delims^= %%i in (' cmd /u /von /c "echo(!string!"^|find /v "" ') do set /a Stringlength += 1

:Eingabe temporär speichern
>"%intemp%" find /n /v ""

:suchen der Zeichenfolge und Zeile bestimmen und speichen
set "NRout="
for /f "tokens=*delims=" %%a in (' find "%string%"^<"%intemp%" ') do if not defined NRout (set "LineStr=%%a"
  for /f "delims=[]" %%b in ("%%a") do set "NRout=%%b"
)
if not defined NRout >&2 echo Zeichenfolge nicht gefunden.& set /a xcode=1 &goto :end
if %NRout% gtr 1 call :Line
call :LineStr

:end
del "%intemp%"
exit /b %xcode%

:LineStr Suche nur jeden ersten Buchstaben des Strings in der Treffer-Zeile dann Ausgabe bis dahin
for /f eol^=^

^ delims^= %%a in ('cmd /u /von /c "echo(!String!"^|findstr .') do (
  for /f "delims=[]" %%i in (' cmd /u /von /c "echo(!LineStr!"^|find /n "%%a" ') do (
    setlocal enabledelayedexpansion
    for /f %%n in ('set /a %%i-1') do if !LineStr:^~%%n^,%stringlength%! equ !string! (
      set "Lineout=!LineStr:~0,%%n!!string!"
      echo(!Lineout:*]=!
      exit /b
    )
) )
exit /b 

:Line vorige Zeilen ausgeben
for /f "usebackq tokens=* delims=" %%i in ("%intemp%") do (
  for /f "tokens=1*delims=[]" %%n in ("%%i") do if %%n EQU %NRout%  exit /b
  set "Line=%%i"
  setlocal enabledelayedexpansion 
  echo(!Line:*]=!
  endlocal
)
exit /b

@echo off
:: CUTwithWildcards.cmd
:noOption
if "%~1" neq "" goto :nohelp
echo Gibt eine Ausgabe ohne die angebene Zeichenfolge.
echo Der Rest wird abgeschnitten.&echo(
echo %~n0 "Zeichenfolge" B n E [/i] &echo(
echo    Zeichenfolge    String zum Durchsuchen
echo    B   Zeichen Wonach am Anfang gesucht wird
echo    n   Auszulassende Zeichenanzahl
echo    E   Zeichen was das Ende der Zeichen Bestimmt
echo    /i  Case intensive
exit /b
:nohelp
setlocal disabledelayedexpansion
set  "Original=%~1"
set     "Begin=%~2"
set /a    Excl=%~3 ||echo Syntaxfehler.>&2 &&exit /b 1
set       "End=%~4"
if not defined end echo Syntaxfehler.>&2 &exit /b 1
set   "CaseInt=%~5"
:: end Setting Input Param
set       "out="
set      "more="
call :read Original
if errorlevel 1 echo Zeichenfolge nicht gefunden.>&2
exit /b
:read VarName B # E [/i]
for /f "delims=[]" %%a in (' cmd /u /von /c "echo  !%~1!"^|find /n %CaseInt% "%Begin%" ') do (
  if defined out exit /b 0
  for /f "delims=[]" %%b in (' cmd /u /von /c "echo !%1!"^|more +%Excl%^|find /n %CaseInt% "%End%"^|find "[%%a]" ') do (
    set "out=1"
    setlocal enabledelayedexpansion
    set "In=  !Original!"
    set "In=!In:~,%%a!"
    echo !In:^~2!
    endlocal
) )
if not defined out exit /b 1 
exit /b

::oneliner for CMDLine
set "Dq=""
for %i in ("*S??E*") do @set "out=1" &for /f "delims=[]" %a in ('cmd/u/c "echo  %i"^|find /n "S"') do @if defined out for /f "delims=[]" %b in ('cmd/u/c "echo %i"^|more +2^|find /n "E"^|find "[%a]"') do @if %a equ %b set "out=" & set in= "%i" &cmd /v/c echo ren "%i" !in:^~0^,%a!!Dq!)
0
pieh-ejdsch