编辑-@jeb是正确的。这是可行的,但确实非常缓慢。
@echo off
setlocal enableextensions enabledelayedexpansion
set "_input=Th""i\s&& is not good _maybe_???"
set "_output="
:loop
if not defined _input goto endLoop
set "_buf=!_input:~0,1!"
set "_input=!_input:~1!"
echo "!_buf!"|findstr /i /r /c:"[a-z 0-9_]" > nul && set "_output=!_output!!_buf!"
goto loop
:endLoop
echo !_output!
endlocal
所以,回到绘图板。如何使其更快?让我们尝试尽可能少地执行操作,并使用尽可能长的子字符串。因此,分两步进行]
1.-删除所有可能产生问题的不良字符。为此,我们将使用for命令的功能来将这些字符标识为定界符,然后将其余的上帝字符部分结合在一起]]
2.-删除其余的坏字符,使用有效字符作为定界符在字符串中找到它们,以找到坏字符的子字符串,然后在字符串中替换
所以,我们以(sintax适应于此处已回答的内容)] >>
@echo off
setlocal enableextensions enabledelayedexpansion
rem Test empty string
call :doClean "" output
echo "%output%"
rem Test mixed strings
call :doClean "~~asd123#()%%%^"^!^"~~~^"""":^!!!!=asd^>^<bm_1" output
echo %output%
call :doClean "Thi\s&& is ;;;;not ^^good _maybe_!~*???" output
echo %output%
rem Test clean string
call :doClean "This is already clean" output
echo %output%
rem Test all bad string
call :doClean "*******//////\\\\\\\()()()()" output
echo "%output%"
rem Test long string
set "zz=Thi\s&& is not ^^good _maybe_!~*??? "
set "zz=TEST: %zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%%zz%"
call :doClean "%zz% TEST" output
echo %output%
rem Time long string
echo %time%
for /l %%# in (1 1 100) do call :doClean "%zz%" output
echo %time%
exit /b
rem ---------------------------------------------------------------------------
:doClean input output
setlocal enableextensions enabledelayedexpansion
set "map=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 "
set "input=%~1"
set "output="
rem Step 1 - Remove critical delimiters
(
:purgeCritical
for /L %%z in (1 1 10) do (
for /f tokens^=1^-9^,^*^ delims^=^=^"^"^~^;^,^&^*^%%^:^!^(^)^<^>^^ %%a in ("!input!") do (
set "output=!output!%%a%%b%%c%%d%%e%%f%%g%%h%%i"
set "input=%%j"
)
if not defined input goto outPurgeCritical
)
goto purgeCritical
)
:outPurgeCritical
rem Step 2 - remove any remaining special character
(
:purgeNormal
for /L %%z in (1 1 10) do (
set "pending="
for /f "tokens=1,* delims=%map%" %%a in ("!output!") do (
set "output=!output:%%a=!"
set "pending=%%b"
)
if not defined pending goto outPurgeNormal
)
goto purgeNormal
)
:outPurgeNormal
endlocal & set "%~2=%output%"
goto :EOF
也许不是最快的,但至少是一个“不错的”解决方案
@echo eof
call :purge "~~asd123#()%%%^"^!^"~~~^:^=asd^>^<bm_1" var
echo (%var%)
goto :eof
:purge StrVar [RtnVar]
setlocal disableDelayedExpansion
set "str1=%~1"
setlocal enableDelayedExpansion
for %%a in ( - ! @ # $ % ^^ ^& + \ / ^< ^> . ' [ ] { } ` ^| ^" ) do (
set "str1=!str1:%%a=!"
)
rem dealing with some delimiters
set "str1=!str1:(=!"
set "str1=!str1:)=!"
set "str1=!str1:;=!"
set "str1=!str1:,=!"
set "str1=!str1:^^=!"
set "str1=!str1:^~=!"
set "temp_str="
for %%e in (%str1%) do (
set "temp_str=!temp_str!%%e"
)
endlocal & set "str1=%temp_str%"
setlocal disableDelayedExpansion
set "str1=%str1:!=%"
set "str1=%str1::=%"
set "str1=%str1:^^~=%"
for /f "tokens=* delims=~" %%w in ("%str1%") do set "str1=%%w"
endlocal & set "str1=%str1%"
endlocal & if "%~2" neq "" (set %~2=%str1%) else echo %str1%
goto :eof
仍然无法处理~ and =
,但是正在处理
EDIT: =
现在将被清除编辑:
~
现在将被清除
这是我编写的允许用户输入的程序,它可以防止用户使用任何字符或空格(标准键盘)。我将其用作辅助程序并从主批处理程序中调用它,但是可以将其转换为功能/标签。
此解决方案成功删除了所有非字母数字字符。
@ECHO OFF
::: Using this Program:
:::
::: Establish Filepath For the Filter:
::: SET smartFilter=%userprofile%\foldername\smartVerify.bat
::: When Needing User Input:
::: SET "VarName=VariableName"
::: SET "title=TitleForYourInputBox"
::: SET "Default=DefaultValueForYourVariable"
::: CALL "%smartVerify%" %VarName% %title% %Default%
::: Passes the Name of the variable being assigned to the input box, and is used
::: to pass the accepted Value Back to the Variable being Set.
SET testinput=%~1
::: Assign A Title For your Input Box
SET MyTitle=%~2
::: Passes a Default value for the Variable to the Input Box.
SET VariableDefault=%~3
::: Expand testinput to the Name of the Variable to be Assigned, And ensure undefined.
SET %testinput%=
::: Ensure Undefined Value for Input
SET input=
:main
::: Exit Filter once Acceptable Variable is Set
IF DEFINED input GOTO return
::: Create and start VBS script to Launch an Input Box and Store the input to text file for retrieval from this Batch program.
(
ECHO Dim objFSO 'File System Object
ECHO Set objFSO = CreateObject("Scripting.FileSystemObject"^)
ECHO Dim objTS 'Text Stream Object
ECHO Const ForWriting = 2
ECHO Set objTS = objFSO.OpenTextFile("%userprofile%\inputTest.txt", ForWriting,
True^)
ECHO objTS.Write(InputBox("Please enter a %testinput% to
continue.","%MyTitle%","%VariableDefault%"^)^)
ECHO objTS.Close(^)
ECHO Set bjFSO = Nothing 'Destroy the object.
ECHO Set objTS = Nothing 'Destroy the object.
) >GetInput.vbs
START GetInput.vbs
::: Convey Keypress required to Continue After 'OK' selected on Input Box
::: Adjust according to your needs.
ECHO \e[32;1H \e[K \e[32;110H\e[36m(\e[34mN\e[36m)ext\e[32m
::: Pause Required to prevent script form continuing before input has been made.
::: Preferred Option Is to use CHOICE with /T (Timeout Switch) to set a delay, and /D
::: (Default switch) To assign a default, then return to main as your default if Time
::: elapses (After passing through InvInput to close the vbs)
CHOICE /T 20 /C nq /N /D n >nul
IF ERRORLEVEL ==2 GOTO invInput
IF ERRORLEVEL ==1 GOTO loadinput
:loadinput
::: Insist on user Input prior to attempting to load input.
IF NOT EXIST "%userprofile%\inputTest.txt" GOTO invInput
::: Retrieve variable value created in Input Box
<%userprofile%\inputTest.txt (
SET /P input=
)
**********”变量的测试从这里开始。 **********
::: Test to ensure Variable defined. Needed here to prevent environment variable not defined message ahead of next test, should the variable not be defined.
IF NOT DEFINED input GOTO invInput
::: Test for Doublequotes and reset variable if present
SET Input | FIND """" >NUL
IF NOT ERRORLEVEL 1 SET Input=
IF NOT DEFINED input GOTO invInput
::: Test for tilde and reset variable if present
SET Input | FIND "~" >NUL
IF NOT ERRORLEVEL 1 SET Input=
IF NOT DEFINED input GOTO invInput
::: Test for Spaces. Remark Out if Spaces Permissable.
IF NOT "%input%"=="%input: =%" GOTO invInput
::: Test for all other standard Symbols. Remark out any characters your wish to Permit.
IF NOT "%input%"=="%input:&=%" GOTO invInput
IF NOT "%input%"=="%input:(=%" GOTO invInput
IF NOT "%input%"=="%input:)=%" GOTO invInput
IF NOT "%input%"=="%input:<=%" GOTO invInput
IF NOT "%input%"=="%input:>=%" GOTO invInput
IF NOT "%input%"=="%input:{=%" GOTO invInput
IF NOT "%input%"=="%input:}=%" GOTO invInput
IF NOT "%input%"=="%input:]=%" GOTO invInput
IF NOT "%input%"=="%input:[=%" GOTO invInput
IF NOT "%input%"=="%input:#=%" GOTO invInput
IF NOT "%input%"=="%input:^=%" GOTO invInput
IF NOT "%input%"=="%input:+=%" GOTO invInput
IF NOT "%input%"=="%input:-=%" GOTO invInput
IF NOT "%input%"=="%input:/=%" GOTO invInput
IF NOT "%input%"=="%input:\=%" GOTO invInput
IF NOT "%input%"=="%input:|=%" GOTO invInput
IF NOT "%input%"=="%input:$=%" GOTO invInput
IF NOT "%input%"=="%input:!=%" GOTO invInput
IF NOT "%input%"=="%input:?=%" GOTO invInput
IF NOT "%input%"=="%input:@=%" GOTO invInput
IF NOT "%input%"=="%input:'=%" GOTO invInput
IF NOT "%input%"=="%input:`=%" GOTO invInput
IF NOT "%input%"=="%input:,=%" GOTO invInput
IF NOT "%input%"=="%input:.=%" GOTO invInput
IF NOT "%input%"=="%input:;=%" GOTO invInput
GOTO main
**********对变量的测试到此结束。 **********
:invInput
SET input=
IF EXIST "GetInput.vbs" (
DEL /Q "GetInput.vbs"
)
::: Conveys To the User that Input is not Acceptable. Adjust According to your needs
ECHO \e[32;1H \e[K \e[32;1H\e[33mInput of a\e[34m %testinput% \e[33mis Required. \e[31mSpaces and Symbols are Not Permitted.\e[32m
::: "%denied%" is the filepath for another batch/vbs script I use to play an audiofile indicating failure. Not required.
::: CALL "%denied%"
:: Terminates the vbs script
taskkill /pid WScript.exe /T >nul
:: Ensure enough time allowed for script to terminate before Relaunching
Timeout 2 >nul
GOTO main
:return
::: assigns the input value to the variable name being validated.
SET %testinput%=%input%
SET input=
IF EXIST "%userprofile%\inputTest.txt" (
DEL /Q "%userprofile%\inputTest.txt"
)
IF EXIST "GetInput.vbs" (
DEL /Q "GetInput.vbs"
)
GOTO :EOF