使用字符串作为分隔符拆分字符串

37

我正在尝试在批处理文件中使用字符串(而不是字符)作为分隔符来拆分一个字符串。

该字符串的格式为:

string1 by string2.txt
分隔符是by(是的,空格,单词'by',后跟空格)。我想要的输出是:
string1

string2

所以,基本上,通过分隔符by将字符串分成两个部分,并从第二个字符串中删除后缀。我该怎么做?

5个回答

56

试试这个:

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

也就是说,取以空格或点分隔的第一个和第三个标记...


简短而美好 - 尽管分隔符字符串可以是任何单词,而不仅仅是“by”。 - Stephan
检查 by 作为分隔符:for /f "tokens=1-3 delims=. " %%a in ("%string%") do ( if "%%b"="by" echo %%a, %%c ) - Stephan
2
这样更简单: for /F "tokens=1,2 delims=." %%a in ("%string: by =.%") do echo %%a, %%b - Aacini
3
不,谢谢。我认为原帖的作者应该意识到答案是要选择第一个和第三个单词,也就是说,我不认为他想要第二个单词恰好是“by”(仅代表我的观点)。 - Aacini
1
@Annan:for /F "tokens=1,2 delims=." %%a in (^"%var:"=.%^") do echo %%a,%%b - Aacini
显示剩余5条评论

19

我最近发现了一个有趣的技巧,可以使用字符串作为分隔符来“拆分字符串”,所以我忍不住要在这里发布它作为一个新答案。请注意,“显然问题不准确。首先,string1和string2都可以包含空格。其次,string1和string2都可以包含&符号。”这种方法正确地适用于新规范(在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%"

有关 split 方法的更多详细信息,请参见 此帖子


2
你能解释一下为什么这个能工作吗?这对我来说太混乱了。 - Andrew
5
@安德鲁:很简单...这行代码:set "string1=%str: by =" & set "string2=%" 只是将字符串变量 str 中的 " by " 替换为 " & set "string2=,然后执行替换后的代码。我建议您在文本编辑器中进行相同的操作:首先输入此行代码:set "string1=string1&with spaces by string2&with spaces.txt" 然后执行上述替换;得到的结果应该是:set "string1=string1&with spaces" & set "string2=string2&with spaces.txt"。您还可以删除 @echo off 这一行代码,运行程序并在屏幕上查看执行的代码。 - Aacini

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

GOTO :EOF

上述的SET命令将删除不需要的数据。在加号之间显示的结果表明没有空格。

公式: set var=%somevar:*string1=string2%

将把所有字符到string1的部分替换为string2后,将其赋值给var。在set命令中使用引号可以确保行尾的任何多余空格不会包含在赋值的值中。


2
有没有办法使用它来获取“by”之前的部分?我尝试了SET“string2 =%string:by * =%”,但那行不通。 - Dennis van Gils
@magoo,看起来你的方法非常整洁,我用它来编辑我的注册表,但是当%LOCALAPPDATA%\Microsoft\WindowsAppsPATH变量中时,它似乎不起作用,我通过将其删除来解决这个问题,使用这种方法完成所需操作后,再重新添加它。 - Jonny Soe
@JonnySoe:我听不懂你在说什么。你需要发布一个问题,明确定义前置条件、期望的结果以及你正在使用的方法。 - Magoo
@Magoo,抱歉我犯了错误,当我编辑注册表时,我匹配了REG_SZ,所以它无法通过REG_SZ分隔符拆分字符串。我使用了setx /m不必要地删除了WindowsApps,这将更改注册表类型为REG_SZ而不是REG_EXPAND_SZ,然后现在通过此分隔符拆分可以正常工作,谢谢! - Jonny Soe

2

我扩展了Magoos的答案,以获取两个所需的字符串:

@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%+

编辑:仅为证明,我的解决方案也可以满足额外的要求:
@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

输出:

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

谢谢,但显然我的问题不准确。首先,string1和string2都可以包含空格。其次,string1和string2都可以包含和号('&')。感谢所有的回答,希望有人能考虑到这两个额外的条件并给出答案。 - Bud

0

我找到了两个使用无限或特定字符串进行分割的较旧脚本。 这些方法总是很有用。

https://www.administrator.de/contentid/226533#comment-1059704 https://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!)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接