Removing non alphanumeric characters in a batch variable

后端 未结 3 809
慢半拍i
慢半拍i 2021-01-03 08:07

In batch, how would I remove all non alphanumeric (a-z,A-Z,0-9,_) characters from a variable?

I\'m pretty sure I need to use findstr and a regex.

3条回答
  •  我在风中等你
    2021-01-03 08:38

    EDITED - @jeb is right. This works but is really, really slow.

    @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
    

    So, back to the drawing board. How to make it faster? lets try to do as less operations as we can and use as much long substring as we can. So, do it in two steps

    1.- Remove all bad characters that can generate problems. To do it we will use the hability of for command to identify these chars as delimiters , and then join the rest of the sections of god characters of string

    2.- Remove the rest of the bad characters, locating them in string using the valids charactes as delimiters to find substrings of bad characters, replacing then in string

    So, we end with (sintax adapted to what has been answered here)

    @echo off
    
        setlocal enableextensions enabledelayedexpansion
    
        rem Test empty string
        call :doClean "" output
        echo "%output%"
    
        rem Test mixed strings
        call :doClean "~~asd123#()%%%^"^!^"~~~^"""":^!!!!=asd^>^^^ %%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
    

    Maybe not the fastest, but at least a "decent" solution

提交回复
热议问题