Board logo

标题: [文本处理] 批处理如何去掉字符串两边的空格 [打印本页]

作者: 胡子轩    时间: 2008-1-2 19:12     标题: 批处理如何去掉字符串两边的空格

想写一个可以去掉字符串两边空格的批处理,做为函数调用,可是却不知从何下手
请诸位帮忙.......
如 set "str=    abc d  "
结果为
"str=abc d"

[ 本帖最后由 胡子轩 于 2008-1-3 09:55 编辑 ]
作者: youxi01    时间: 2008-1-2 20:06

当然,可以用if来检测。
但是因为受 联盟里 3742版主的影响,不太喜欢if,所以尽量不用...
测试代码:
  1. @echo off
  2. set "str=    abc   df  fd       d     "
  3. for /f "tokens=* delims= " %%i in ("%str%") do set "str=%%i"
  4. set str=%str: = # %
  5. call :Rev "%str%"
  6. for /f "tokens=* delims=#" %%i in ("%Res%") do set "str=%%i"
  7. set "str=%str:#= # %"
  8. call :Rev "%str%"
  9. echo "%Res:#= %"
  10. pause>nul
  11. :Rev str
  12. set "Res="
  13. for %%i in (%~1) do call set Res=%%i%%Res%%
复制代码

作者: ieutk    时间: 2008-1-2 21:22

我来一个if的
  1. @echo off
  2. set "str=    abc d  "
  3. for /f "tokens=* delims= " %%a in ("%str%") do (
  4.         set "var=%%a"
  5.         call :ie
  6.     )
  7. echo.
  8. echo  去除空格前:  [%str%]
  9. echo.
  10. echo  去除空格后:  [%var%]
  11. echo.
  12. pause&goto :eof
  13. :ie
  14. if "%var:~-1%"==" " (set "var=%var:~0,-1%"&goto ie) else goto :eof
复制代码

作者: youxi01    时间: 2008-1-2 21:46

呵呵,楼上的不错,先通过for循环消除开头的 空格,然后用if来检测(个人不太喜欢)...
也有几点建议:
1、标签中的变量设置不甚恰当。
程序中的var变量在这里最好放到标签:ie里,特别是比较长的程序的话,你就知道好处了。
2、那个else似乎没什么用处。
改成以下代码是否好点呢?
  1. @echo off
  2. set "str=    abc d  "
  3. for /f "tokens=* delims= " %%a in ("%str%") do call :ie "%%a"
  4. echo.
  5. echo  去除空格前:  [%str%]
  6. echo.
  7. echo  去除空格后:  [%var%]
  8. echo.
  9. pause&goto :eof
  10. :ie str
  11. set "var=%~1"
  12. if "%var:~-1%"==" "  call :ie "%var:~0,-1%"
复制代码

作者: ieutk    时间: 2008-1-2 22:13

呵呵,楼上的不错,先通过for循环消除开头的 空格,然后用if来检测(个人不太喜欢)...
也有几点建议:
1、标签中的变量设置不甚恰当。
程序中的var变量在这里最好放到标签:ie里,特别是比较长的程序的话,你就知道好处了。
2、那个else似乎没什么用处。
改成以下代码是否好点呢?


谢谢提点,确实,那个变量var放在子标签中很好,"程序"归"程序","函数"归"函数".

我个人也很喜欢用"函数"的方式来编写代码,再者水平有限,编写不出什么大型

的脚本,所以在这些方面有所忽略.
  1. if "%var:~-1%"==" "  call :ie "%var:~0,-1%"
复制代码
你这一行代码以前没有看到这种用法,现在才知道,学习ing. . .
作者: novaa    时间: 2008-1-2 22:56

学习了。
@echo off
set "str=    abc   df  fd       d     "
for /f "tokens=* delims= " %%i in ("%str%") do set "str=%%i"
echo %str%
这里的是abc   df  fd       d  
不是去掉空格了吗?
作者: youxi01    时间: 2008-1-2 23:06

呵呵,你这个其实 还没去掉d后面的空格的///
作者: ieutk    时间: 2008-1-2 23:07

No,非也,6楼请仔细看咯,d后面还有空格呢,只是看不到而己,看下面代码,用括号括起来就方便看了
  1. @echo off
  2. set "str=    abc   df  fd       d     "
  3. for /f "tokens=* delims= " %%i in ("%str%") do set "str=%%i"
  4. echo [%str%]
  5. pause
复制代码

[ 本帖最后由 ieutk 于 2008-1-2 23:09 编辑 ]
作者: namejm    时间: 2008-1-2 23:24

  转一下以前写的代码:

  去掉左侧空格1:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. for /f "tokens=*" %%i in ("%str%") do echo "☆%%i☆"
  4. pause
复制代码
  去掉左侧空格2:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. :intercept
  4. if "%str:~0,1%"==" " set "str=%str:~1%"&goto intercept
  5. echo "☆%str%☆"
  6. pause
复制代码
  去掉右侧空格1:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. for /f "delims=" %%i in ("%str%") do echo "☆%%~nxi☆"
  4. pause
复制代码
  去掉右侧空格2:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. :intercept
  4. if "%str:~-1%"==" " set "str=%str:~0,-1%"&goto intercept
  5. echo "☆%str%☆"
  6. pause
复制代码
  去掉首尾空格1:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. for /f "tokens=*" %%i in ("%str%") do echo "☆%%~nxi☆"
  4. pause
复制代码
  去掉首尾空格2:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. :intercept_left
  4. if "%str:~0,1%"==" " set "str=%str:~1%"&goto intercept_left
  5. :intercept_right
  6. if "%str:~-1%"==" " set "str=%str:~0,-1%"&goto intercept_right
  7. echo "☆%str%☆"
  8. pause
复制代码
  去掉所有空格:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. set "str=%str: =%"
  4. echo "☆%str%☆"
  5. pause
复制代码
  以上代码能兼容除双引号外的其他特殊字符。
作者: youxi01    时间: 2008-1-2 23:42

呵呵,这个以前就拜读过了,只是当初没太注意,也没去想原理;原来蛮有应用价值的嘛!
精品就是精品啊,哈哈!!
作者: ieutk    时间: 2008-1-2 23:53

namejm出手必属精品
作者: 随风    时间: 2008-1-3 01:43

也来个不能显示特殊字符,
去除首尾空格
:
  1. @echo off
  2. set "str=   ab     c    "
  3. call :lis %str%
  4. pause
  5. :lis
  6. echo ☆%*☆
  7. goto :eof
复制代码

作者: youxi01    时间: 2008-1-3 07:46

好,值得加分!!
在联盟qw版主写的 数字排序 程序里出现过这种用法:%*
作者: youxi01    时间: 2008-1-4 19:35

对于楼上的 namejm 和 随风 兄弟的代码,应该来说,可以比较好的解决楼主的问题,但是也有瑕疵:
1、随风兄弟的现行代码 无法处理 特殊字符;
2、namejm的代码:
  1. @echo off
  2. set "str=   ab c&>!   "
  3. for /f "tokens=*" %%i in ("%str%") do echo "☆%%~nxi☆"
  4. pause
复制代码
namejm的代码是利用了CMD对文件路径、文件名的“解析漏洞”很好的去掉了字符串首尾两端的空格,但是还存在一些小问题,测试代码:
  1. @echo off
  2. set "str=   ab\ c&>!  .  "
  3. for /f "tokens=*" %%i in ("%str%") do echo "☆%%~nxi☆"
  4. pause
复制代码
运行结果会抛弃"ab"和"."
呵呵,欢迎大家继续讨论!
作者: 随风    时间: 2008-1-5 13:34

极其臃肿.
:
  1. @echo off
  2. set "str=   a\b c&>! .  "
  3. call :lis
  4. set flag=1
  5. :lis
  6. set var=
  7. for /l %%i in (1 1 100) do (
  8.    if defined str (
  9.    call set "var=%%var%%%%str:~-1%%"
  10.    call set "str=%%str:~0,-1%%"
  11. ))
  12. set "str=%var%"
  13. for /f "tokens=*" %%a in ("%str%") do set "str=%%a"
  14. if not defined flag goto :eof
  15. echo "%str%"
  16. pause
复制代码





...
作者: xxx3212    时间: 2008-1-19 23:00

真他齐全 特别是 %%~nxi 的用法
作者: tiandyoin    时间: 2023-8-4 17:00

本帖最后由 tiandyoin 于 2023-8-4 21:38 编辑
  1. @goto :main_20230424_102850
  2. @Usage:
  3. cd /d "%~dp0" & call "字符串 Trim.bat" :Trim[Ext] arg1_name L[eft] R[ight]
  4. :main_20230424_102850
  5. @echo off||code by tiandyoin&title "字符串 Trim.bat"  
  6. :: 约定 %~1 为 :Trim... 其中的一个标签(Label)。  
  7. if "%~1"=="" (
  8. call :test_20230424_102850  
  9. cd /d "%~dp0" & call "判断 双击运行 or 命令提示符窗口.bat" :where-am-i
  10. ) else (
  11. :: 即 call :Trim[Ext] arg1_name L[eft] R[ight]
  12. call %*
  13. )
  14. @goto :eof
  15. :test_20230424_102850
  16. @echo off&setlocal enabledelayedexpansion
  17. set "str=   ""test.txt  "".  .. ...   "
  18. echo [!str!]
  19. call :Trim str
  20. echo [!str!]
  21. set "str=   ""test.txt  "".  .. ...   "
  22. echo [!str!]
  23. call :Trim str "" ""
  24. echo [!str!]
  25. set "str=   ""test.txt  "".  .. ...   "
  26. echo [!str!]
  27. call :Trim str L, R
  28. echo [!str!]
  29. set "str=   ""test.txt  "".  .. ...   "
  30. echo [!str!]
  31. call :TrimExt str Right
  32. echo [!str!]
  33. @goto :eof
  34. @rem Usage:
  35. rem 需要调用者提供“延迟变量扩展环境”。  
  36. :Trim  <arg1_name [,L[eft] ,R[ight]]>
  37. @echo off&setlocal enabledelayedexpansion
  38. set fst=0
  39. set lst=0
  40. set "input=!%~1!"
  41. if /i not "%~2"=="L" if /i not "%~2"=="Left" if /i not "%~2"=="" goto :Trim.lTrim.EOF
  42. :Trim.lTrim
  43. set ch=!input:~0,1!
  44. @rem 如果 ch 是双引号,需要凑成对组成引用闭环。
  45. if not "!ch!!ch!"=="  " if not "!ch!!ch!"==" " goto :Trim.lTrim.EOF
  46. set "input=!input:~1!"
  47. set /a fst+=1
  48. goto :Trim.lTrim
  49. :Trim.lTrim.EOF
  50. if /i not "%~2"=="R" if /i not "%~2"=="Right" if /i not "%~2"=="" if /i not "%~3"=="R" if /i not "%~3"=="Right" if /i not "%~3"=="" goto :Trim.EOF
  51. :Trim.rTrim
  52. set ch=!input:~-1!
  53. if not "!ch!!ch!"=="  " if not "!ch!!ch!"==" " goto :Trim.EOF
  54. set "input=!input:~0,-1!"
  55. set /a lst-=1
  56. goto :Trim.rTrim
  57. :Trim.EOF
  58. if !lst!==0 (set "lst=") else (set "lst=,!lst!")
  59. endlocal & set "%~1=!%~1:~%fst%%lst%!"
  60. @goto :EOF
  61. @rem Usage:
  62. rem 需要调用者提供“延迟变量扩展环境”。  
  63. rem 增加功能: 去除右边 '.'
  64. :TrimExt  <arg1_name [,L[eft] ,R[ight]]>
  65. @echo off&setlocal enabledelayedexpansion
  66. set fst=0
  67. set lst=0
  68. set "input=!%~1!"
  69. if /i not "%~2"=="L" if /i not "%~2"=="Left" if /i not "%~2"=="" goto :TrimExt.lTrimExt.EOF
  70. :TrimExt.lTrimExt
  71. set ch=!input:~0,1!
  72. @rem 如果 ch 是双引号,需要凑成对组成引用闭环。
  73. if not "!ch!!ch!"=="  " if not "!ch!!ch!"==" " goto :TrimExt.lTrimExt.EOF
  74. set "input=!input:~1!"
  75. set /a fst+=1
  76. goto :TrimExt.lTrimExt
  77. :TrimExt.lTrimExt.EOF
  78. if /i not "%~2"=="R" if /i not "%~2"=="Right" if /i not "%~2"=="" if /i not "%~3"=="R" if /i not "%~3"=="Right" if /i not "%~3"=="" goto :TrimExt.EOF
  79. :TrimExt.rTrimExt
  80. set ch=!input:~-1!
  81. if not "!ch!!ch!"=="  " if not "!ch!!ch!"==" " if not "!ch!!ch!"==".." goto :TrimExt.EOF
  82. set "input=!input:~0,-1!"
  83. set /a lst-=1
  84. goto :TrimExt.rTrimExt
  85. :TrimExt.EOF
  86. if !lst!==0 (set "lst=") else (set "lst=,!lst!")
  87. endlocal & set "%~1=!%~1:~%fst%%lst%!"
  88. @goto :EOF
  89. @rem Usage:
  90. rem 需要调用者提供“延迟变量扩展环境”。  
  91. rem 功能: 去除指定字符左右两边的其它字符。
  92. rem 方法:
  93. rem 使用 Set 替换英文双引号为中文双引号,替换指定字符等为双引号,
  94. rem 再使用 Set 去除引号两边字符,最后还原回英文双引号。
  95. rem         %var:*"=set "var=%
  96. :TrimBesideAssigner  <arg1_name [,%Assigner% ,L[eft] ,R[ight]]>
  97. REM 未完成
  98. @goto :EOF
复制代码
  1. 【测试用例】
  2. "转义字符.txt"
  3. 以下测试空行:
  4.    
  5. 下面是 中国DOS联盟 @bjsh 的例子:
  6. "aou"eo
  7. 下面一行需要 findstr /n
  8. ;euou%^>
  9. ::::aeui
  10.    
  11. :::E2uo alejou 3<o2io|
  12. ^aue||%ou
  13. aoue eou 2
  14. euo 8
  15. ege#6758!7^^9098!98%$&^
  16. ueyi^^^^aueuo2
  17. ~ ! @ # $ % ^ & * ( () " ok " No " <>nul
  18. ege#6758^^^!7^^^^9098^!98%$&^^
  19. ~ ! @ # $ %"  ^  "& * ( () " ok " No " <>nul
  20. sdsdg:sadgs
  21. kl&>jl^k!tsd!21%mk%gd
  22. kl&>jlk^!tsd^!21%mk%gd
  23. dgssdgdg^gds^gdsa
  24. 下面是 CSDN @tiandyoin 的例子:
  25. @REM cmd [/c, /k] 命令中需要双引号的特殊字符是:
  26. @REM      <white space>
  27. @rem      & < > [ ] { } ^ = ; ! ' + , ` ~
  28. @REM 详见:
  29. @REM "批处理之家\ntcmds.chs.chm"
  30. @REM      &()[]{}^=;!'+,`~
  31. %~
  32. %~:
  33. %~:=%
  34. :123
  35. :
  36. %a%
  37. !b!
  38. "%a%"
  39. "!b!"
  40. %%a%%
  41. ^!b^!
  42. %a!%b!
  43. !b%a!%
  44. %%a%
  45. ^!b!
  46. a"%b"%c"
  47. a"!b"!c"
  48. "a b " c"
  49. "a b "" c"
  50. ""a b "" c"
  51. ""a b "" c""
  52. """a b "" c"""
  53. (()((
  54. [\s\t ]
  55. :test"^!~:^=!" % ~:=% ^0&((()||><>> `@#$*-_+{{}[]]\;',.?/ %~0 !~0 %空变量% !空变量! %空变量:空值1=空值2% !空变量:空值1=空值2! "
  56. :test"^!~:^=!" % ~:=% ^0&((()||><>>^^ ^^^ ^^^^  `@#$*-_+{{}[]]\;',.?/ %~0 !~0 %空变量% !"空变量! %"空变量:空值1=空值2% !空变量:空值1=空值2! "
  57.   1:c:\3/%5:\%1 %* 2<1.bug "!a!>" & !b!<"!c!"|!d! "?4*6?%e%"%f%" && (( %!g!% || !%h%! )  
  58.   1:c:\3/%5:\%1 %* 2<1.bug "!a!>" & !b^!<"=^^!c!"|!d^! "?4*6?%e%"+%f%" && (( %!g!% || !%h%! )  
  59.   1:c:\3/%5:\%1 %* 2<1.bug !i! "!a!>" & !b^!<"=^^!c!"|!d^! "?4*6?%e%"+%f%" && (( %!g!% || !%h%! )   
  60.    " 1:c:\3/%5:\%1 %* 2<1.bug !i! "!a!>" & !b^!<"=^^!c!"|!d^! "?4*6?%e%"+%f%" && (( %!g!% || !%h%! ) ;euou%^>1.txt  "   
  61.    
  62. "update-content": " <p>1.优化程序,提高稳定性,提升用户体验。</p><p>2.订阅即将到期增加提醒。</p><p>3.“我的套餐”中增加显示激活码和邮箱的信息。</p><p>4.优化激活失败提示信息。</p><p>5.程序多开问题优化处理。</p><p>6.windows平台网络诊断数据异常问题。</p><p>7.其它问题优化。</p>",
复制代码
没找到完美的方法,这是我自己写的,尽可能解决问题:
1. 单数个双引号
2. :: 开头的注释
3. ; 开头的隔行作用
4. !! 被误当成取值
5. %% 被误当成取值
6. %~ 闪退
7. ^^^^ 多个的折叠问题

使用 set 去除空格前需要转义特殊字符,因此我没采用这些方法,而使用循环逐一处理每一个字符




欢迎光临 批处理之家 (http://bbs.bathome.net/) Powered by Discuz! 7.2