【问题标题】:Batch to keep only certain characters in a string批处理以仅保留字符串中的某些字符
【发布时间】:2013-05-03 14:29:39
【问题描述】:

我有一个来自批处理文件中 for 循环的变量:

for /f Tokens^=3^,10delims^=^<^>^" %%i in ('findstr -i "href=" bookmarks.html') do (
   set str1=%%j

如何在变量 str1 中只保留某些字符? : a-z, A-Z, 0-9

示例: Blabla&lt;/2378:., => Blabla2378

提前致谢。

【问题讨论】:

  • 难道没有解决方案:将[^a-zA-Z0-9] 替换为""?如何使用 BATCH 进行搜索/替换正则表达式?
  • 没有批量“替换”工具,但Windows可以使用sed

标签: string for-loop batch-file trim


【解决方案1】:
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "string=+"
FOR /l %%i IN (32,1,127) DO CALL :addstring %%i
ECHO !string!
FOR /l %%i IN (100,-1,0) DO CALL :delstring %%i
ECHO !string!
GOTO :eof

:addstring
CALL CMD /c EXIT /b %1
SET "string=!string!!=exitcodeascii!"
GOTO :eof

:delstring
SET cp=!string:~%1!
IF NOT DEFINED cp GOTO :EOF 
ECHO abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ|FIND "!string:~%1,1!" >NUL 2>nul
IF NOT ERRORLEVEL 1 GOTO :eof
SET /a cp=%1+1
SET "string=!string:~0,%1!!string:~%cp%!"
GOTO :eof

嗯 - 这是一种至少可以做很多事情的方法。

ADDSTRING 例程只是构建一个字符列表,以“+”开头,除了证明字符串以空格开头之外没有其他原因。

通过重复调用delstring,从字符串的末尾向后运行,每个不在字母列表中的字符都会被删除。


编辑以应用示例字符串
@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET "string=+-=++()*&^^^#!!!<--remove all of those and those----->.,?/';][}{__"
ECHO before: !string!
FOR /l %%i IN (70,-1,0) DO CALL :delstring %%i
ECHO after : !string!
SET "string= "blablabla23:/./é'""
ECHO before: !string!
FOR /l %%i IN (20,-1,0) DO CALL :delstring %%i
ECHO after : !string!
GOTO :eof

:delstring
SET cp=!string:~%1!
IF NOT DEFINED cp GOTO :EOF 
ECHO abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ|FIND "!string:~%1,1!" >NUL 2>nul
IF NOT ERRORLEVEL 1 GOTO :eof
SET /a cp=%1+1
SET "string=!string:~0,%1!!string:~%cp%!"
GOTO :eof

对 OP 的警告:语法 SET string = "something" IS 对空格的存在敏感。它设置变量 "string " 的值 - 而不是 "string" - 变量名称中包含空格。同样,前导空格和双引号也包含在分配的值中。

语法set "var=value" 旨在确保行上的任何尾随空格不包含在分配给变量var 的值中。请注意,此语法允许在分配的字符串中使用双引号。


其他方法

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
SET str1="blabla"
SET "allowedchars=abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"

ECHO before: !str1!
FOR /l %%i IN (70,-1,0) DO CALL :delstr1 %%i
ECHO after : !str1!
SET "str1= "blablabla23:/./é'""
ECHO before: !str1!
FOR /l %%i IN (20,-1,0) DO CALL :delstr1 %%i
ECHO after : !str1!

ECHO ============================ now let's try that again.
ENDLOCAL
SETLOCAL ENABLEDELAYEDEXPANSION
SET str1="blabla"
SET "allowedchars=abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"

ECHO before: !str1!
CALL :delstr2 str1
ECHO after : !str1!
SET "str1= "blablabla23:/./é'""
ECHO before: !str1!
CALL :delstr2 str1
ECHO after : !str1!



GOTO :eof

:delstr1
SET cp=!str1:~%1!
IF NOT DEFINED cp GOTO :EOF 
ECHO !allowedchars!|FIND "!str1:~%1,1!" >NUL 2>nul
IF NOT ERRORLEVEL 1 GOTO :eof
SET /a cp=%1+1
SET "str1=!str1:~0,%1!!str1:~%cp%!"
GOTO :eof

:delstr2
SETLOCAL
SET cp=0
:delstr2a
SET "$_=!%1:~%cp%!"
IF DEFINED $_ SET /a cp+=1&GOTO delstr2a
SET "$_=!%1!"
:delstr2b
IF NOT DEFINED %1 GOTO delstr2done
SET /a cp-=1
IF %cp% lss 0 GOTO delstr2done
ECHO !allowedchars!|FIND "!$_:~%cp%,1!" >NUL 2>NUL
IF NOT ERRORLEVEL 1 GOTO delstr2b
SET /a ca=cp+1
SET "$_=!$_:~0,%cp%!!$_:~%ca%!"
GOTO delstr2b
:delstr2done 
endlocal&SET "%1=%$_%"
GOTO :EOF

批处理异常缓慢。它可以完成这项工作,只是需要时间。我的意思是我也可以在我的后院割草 - 我只是慢慢来。

现在,如果您想处理数千个字符串,大概它们位于一个或多个文件中。您应该找到 SED - 谷歌搜索 GNU SED 将是一个好的开始。

执行您所要求的操作的 SED 行将是

sed s/[^^a-zA-Z0-9]//g <filename >newfilename

需要双插入符号的地方,因为插入符号就CMD.EXE 而言是一个特殊字符,因此需要用插入符号转义。

【讨论】:

  • 非常感谢彼得!但我有点迷路(我不明白这些call cmd 等)你有一个简单示例字符串的示例吗?示例:mystr1 = "blablabla23:/./é'"
  • addstring 例程所做的只是构建一串可打印字符。它不涉及“删除所有非字母”功能。您需要做的就是分配要从中选择非字母数字的任何字符串,然后执行FOR /l...:delstring %%i 命令,括号中三个数字中的第一个至少是字符串string 的长度。 8000 是一个不错的数字 - 但它越大,例程运行所需的时间就越长。我会用几个例子来修改帖子。
  • 谢谢,但我还是迷路了...你有没有一个以@ECHO OFF SETLOCAL ENABLEDELAYEDEXPANSION SET str1="blabla" SET allowedchars="abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ" 开头并以echo str2 结尾的例子,其中str2str1 的清理版本?非常感谢!
  • 有点奇怪:每个字符串需要 1 或 2 秒(平均 50 个字符长)...而且我有 1000 个字符串要处理;)
猜你喜欢
  • 2013-03-23
  • 1970-01-01
  • 2017-07-31
  • 2019-12-21
  • 1970-01-01
  • 1970-01-01
  • 2020-04-10
  • 2022-01-17
  • 1970-01-01
相关资源
最近更新 更多