我如何分割字符串
" This is a text with spaces "
在变量“string”中 在不丢失空格的情况下进入文本部分?
set string="# This is a text with spaces #"
应该分成
"# This"
" is"
" a"
" text"
" with"
" spaces #"
使用For /F "delims= " ...
不起作用,因为它消除了所有空格。
是否有'简单'的解决方案,或者任何人都可以解释如何逐字符解析字符串 所以我可以计算第一个字符的空格,然后读取所有字符直到下一个空格并写入 计数的空格和读取的字符一起到一个新的/ temp变量??
谢谢
答案 0 :(得分:3)
是的,我也不太了解#
。什么是“空间#”,它使它保持在尾随空格,而所有其他元素保持前面但不是前进的空格?
哦,好吧,努力花在询问上=花在回答上的努力。做到这一点,你会做什么。
@if (@a==@b) @end /*
:: batch portion
@echo off
setlocal
call :split "# This is a text with spaces #"
exit /b
:split <string>
cscript /nologo /e:jscript "%~f0" "%~1"
goto :EOF
:: JScript portion */
WSH.Echo(WSH.Arguments(0).match(/\s*\S+/g).join('\n'));
输出:
#
This
is
a
text
with
spaces
#
如果你想要第一个+第二个,倒数第二个+终极元素加入,修改上面脚本的JScript部分如下:
:: JScript portion */
var m = WSH.Arguments(0).match(/\s*\S+/g);
m[0] = m.shift() + m[0];
m[m.length - 2] += m.pop();
WSH.Echo(m.join('\n'));
输出:
# This
is
a
text
with
spaces #
如果您希望每个元素都用引号括起来,请按如下所示更改最后一行:
WSH.Echo('"' + m.join('"\n"') + '"');
输出:
"# This"
" is"
" a"
" text"
" with"
" spaces #"
答案 1 :(得分:2)
我没有批量看到一个简单的解决方案,当然如果你可以考虑使用powershell或javascript,你将使用更合适的字符串操作工具集。
坚持批量要求,你可以逐字逐句地循环,并用这样的东西“收集”你的单词:
@echo off
setlocal enabledelayedexpansion
set "string= This is a text with spaces "
set idx=0
set "word="
set "char="
set "lastchar= "
:loop
if "!string:~%idx%!" equ "" goto :eof
set char=!string:~%idx%,1!
if "%char%" equ " " (
if "%lastchar%" neq " " (
echo [%word%]
set word=%char%
) else (
set word=%word%%char%
)
) else (
set word=%word%%char%
)
set lastchar=%char%
set /a idx=%idx%+1
goto loop
此脚本使用批处理的子字符串功能!string:~%idx%,1
从字符串中抓取单个字符,每个循环递增idx
。然后,当前一个字符不是空格而当前字符不是空格时,只需处理单词(本例中为echo
)。
这写出:
[ This]
[ is]
[ a]
[ text]
[ with]
[ spaces]
请注意,我忽略了您示例中的#
,因为我不明白它们适合的位置。
答案 2 :(得分:2)
诀窍是用一个空格代替连续的空格,其余用一些任意的字符代替。假设你的字符串不包含#
并且不超过9个连续的空格,你可以试试这个
set st=%st: = ########%
set st=%st: = #######%
set st=%st: = ######%
set st=%st: = #####%
set st=%st: = ####%
set st=%st: = ###%
set st=%st: = ##%
set st=%st: = #%
然后您可以使用for /f
解析并用空格替换#
setlocal enabledelayedexpansion
for /f %%a in ("%st%") do (
set ss= %%a
echo !ss:#= !
)
请注意,括号内的set
要求您启用延迟扩展并使用!
语法(请参阅HELP SET
)
但是这种技术只会提取第一个子串。为了概括,你需要另一个技巧,即将空格代入换行符,以便for /f
逐行循环
请注意,为了获取换行符,您需要在set
命令后保留两个空行
set nl=^
rem continue two lines down....
for /f %%a in ("%st: =!nl!%") do (
set ss= %%a
set ss=!ss:#= !
echo [!ss!]
)
答案 3 :(得分:2)
试试这个:
@echo off &setlocal enabledelayedexpansion
set "string=# This is a text with spaces #"
set string1=%string%
for %%i in (%string%) do (
set string1=!string1: %%i = "%%i" !
set /a strings+=1
)
set string1=#"%string1:~1,-1%"#
set string1=%string1:"= "%
for %%i in (%string1%) do (
set /a count+=1
set string2=%%i
set string2=!string2: "=!
set string2=!string2:"=!
if !count! equ 2 (
set $s1=!$s1!!string2!
)else if !count! equ %strings% (
set /a count-=1
call set $s!count!=%%$s!count!%%!string2!
) else set $s!count!=!string2!
)
for /f "tokens=1*delims==" %%i in ('set "$s"') do echo "%%j"
输出:
"# This"
" is"
" a"
" text"
" with"
" spaces #"
答案 4 :(得分:2)
如果我必须完成这个不起眼的任务,我会使用像rojo's answer中那样的混合JScript /批处理技术。但是,我会使用REPL.BAT utility that I have already written。假设我的REPL.BAT位于当前文件夹中,或者位于PATH中的某个位置,则以下内容将起作用:
@echo off
setlocal enableDelayedExpansion
set "string=# This is a text with spaces #"
:: Build an "array" of text parts
set cnt=0
for /f delims^=^ eol^= %%A in ('repl "([^ ])(?= )" "$1\n" xs string') do (
set /a cnt+=1
set "string!cnt!=%%A"
)
:: Print the array values
for /l %%N in (1 1 %cnt%) do echo string%%N=[!string%%N!]
但如果我想要一个纯粹的批量解决方案,我会使用下面相当有效的方法:
@echo off
setlocal enableDelayedExpansion
set "string=# This is a text with spaces #"
:: Define LF to contain a single line feed character (0x0A)
set LF=^
:: Above 2 blank lines are critical - DO NOT REMOVE
:: Insert a line feed before every space
for %%n in ("!LF!") do set "string=!string: =%%~n !"
:loop Remove line feeds sandwiched by spaces
for %%n in ("!LF!") do set "string2=!string: %%~n = !"
if "!string2!" neq "!string!" (
set "string=!string2!"
goto :loop
)
:: Build an "array" of text parts: FOR /F splits the string at line feeds
set /a cnt=0
for /f delims^=^ eol^= %%A in ("!string!") do (
set /a cnt+=1
set "string!cnt!=%%A"
)
:: Print out the array values
for /l %%N in (1 1 %cnt%) do echo string%%N=[!string%%N!]
上述两种解决方案均提供以下输出:
string1=[#]
string2=[ This]
string3=[ is]
string4=[ a]
string5=[ text]
string6=[ with]
string7=[ spaces]
string8=[ #]
请注意,如果由于延迟扩展而导致字符串包含%%A
,则FOR循环!
扩展会破坏结果。通过额外的编码可以消除这种限制。所有其他使用FOR循环的已发布解决方案都受到同样的限制。 (至少他们在写这篇文章的时候就这么做了)