如何在选择命令中使用特殊字符 - 批处理文件
How to use special characters in choice command - Batch File
我想在我的选择命令中添加像 <
|
这样的特殊字符,我该怎么做?
这是我的旧代码:
CHOICE /C ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...."
我希望它是这样的:
CHOICE /C `~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...."
如有任何帮助,我们将不胜感激。
编辑:因为你们中的一些人可能会问为什么我需要这么多选择,我在这里回答。这是因为按下一个无效的选择会给你一个 annoying 的哔哔声,我不喜欢。所以我问了这个问题。
使用选择,你不能。
如果您尝试使用无效字符执行 Choice,您将收到一条消息。例如(插入符号'^' 符号用于转义管道'|',因为这是cmd 的特殊字符):
CHOICE /C ^|
returns:
错误:无效的选择。有效的选择字符是:a-z、A-Z、0-9 和 128 到 254 的 ASCII 值。
可能的解决方法:
您可以使用 SET 来满足您的需求,但是您在批处理脚本中使用变量可能会导致问题。在任何使用这些变量的地方,都需要以转义字符插入符号 (^) 开头。
此解决方案还需要用户在做出选择后按下回车键。
@ECHO OFF
Choose one:
ECHO.
ECHO ^| - 1
ECHO ^> - 2
ECHO A - 3
ECHO ^" - 4
ECHO ^^ - 5
SET /P KeyPressed=Choice? [^|^>A]
IF [^%KeyPressed%]==[^|] ECHO 1 && GOTO END
IF [^%KeyPressed%]==[^>] ECHO 2 && GOTO END
IF [^%KeyPressed%]==[^A] ECHO 3 && GOTO END
IF [^%KeyPressed%]==[^"] ECHO 4 && GOTO END
IF [^%KeyPressed%]==[^^] ECHO 5 && GOTO END
ECHO None of them.
:END
ShowMenu
Sub ShowHelpMenu
outp.writeline " -----------------------------------------------------------------------------"
outp.writeblanklines(1)
outp.writeline " Menu"
outp.writeline " ----"
outp.writeblanklines(1)
outp.writeline " 1 Help 2 HTML Help 3 Version 4 History"
outp.writeblanklines(1)
outp.writeline " 5 Exit"
outp.writeblanklines(1)
outp.write "Filter>"
End Sub
'=============================================
Sub ShowMenu
Do
ShowHelpMenu
Answ=Inp.readline
If Answ = "1" Then
ShowGeneralHelp "TEXT"
Elseif Answ = "2" Then
ShowGeneralHelp "HTML"
Elseif Answ = "3" Then
Version
Elseif Answ = "4" Then
History
Elseif Answ = "5" Then
Exit Do
End If
Loop
End Sub
Th9is 是一个 VBS 文件。
CHOICE 命令只允许字母数字字符,以及十进制字节代码在 128-254 之间的扩展 ASCII 字符。
我已经基于使用 REPLACE 的 hack 编写了 CHOICE 的纯批处理替代品。我的 :getKey
例程可以接受大多数任何字符,并允许您指定允许的字符,并将捕获的字符放入您选择的变量中 - 比乱用 ERRORLEVEL 方便得多。
我最初将例程发布在 http://www.dostips.com/forum/viewtopic.php?f=3&t=7396。 link 还有一个更复杂的例程,可以绝对读取任何键值,包括 NULL,以及一个允许输入屏蔽字符串(每个字符显示星号)的例程。
下面是 :getKey 例程,以及显示用法的示例。如果您希望按键区分大小写,请移除 /I
开关。脚本中嵌入了完整的文档。
Edit - 我已将代码更新到 2.0 版,能够指定提示,并使有效的键列表区分大小写。 不能 的唯一 CHOICE 功能是带有默认响应的超时选项。我没有看到任何合理的方式来提供超时选项。
@echo off
setlocal enableDelayedExpansion
set "valid=0`~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928"
call :getKey /p "Press 8 ...." key valid /i
echo(
echo You pressed !key!
exit /b
::getKey [/P "Prompt"] KeyVar [ValidVar [/I]]
::
:: Read a keypress representing a character between 0x00 and 0xFF and store the
:: value in variable KeyVar. Null (0x00), LineFeed (0x0A), and Carriage Return
:: (0x0D) will result in an undefined KeyVar. On Windows 10, Ctrl-Z (0x1A) will
:: also result in an undefined KeyVar. The simplest way to get an undefined
:: KeyVar is to press the [Enter] key.
::
:: The optional /P parameter is used to specify a "Prompt" that is written to
:: stdout, without a newline. Also, the accepted character is ECHOed after the
:: prompt if the /P option was used.
::
:: The optional ValidVar parameter defines the values that will be accepted.
:: If the variable is not given or not defined, then all characters are accepted.
:: If given and defined, then only characters within ValidVar are accepted. The
:: first character within ValidVar should either be 0, meaning ignore undefined
:: KeyVar, or 1, meaning accept undefined KeyVar. The remaining characters
:: represent themselves. For example, a ValidVar value of 0YN will only accept
:: uppercase Y or N. A value of 1YN will additionally accept [Enter] etc.
::
:: If ValidVar is followed by the optional /I switch, then case of standard
:: English letters is ignored. The case of the pressed key is preserved in
:: the result, but English letters A-Z and a-z are not rejected due to case
:: differences when the /I switch is added.
::
:: Any value (except null) may be entered by holding the [Alt] key and pressing
:: the appropriate decimal code on the numeric keypad. For example, holding
:: [Alt] and pressing numeric keypad [1] and [0], and then releasing [Alt] will
:: result in a LineFeed.
::
:: The only way to enter a Null is by holding [Ctrl] and pressing the normal [2]
::
:: An alternate way to enter control characters 0x01 through 0x1A is by holding
:: the [Ctrl] key and pressing any one of the letter keys [A] through [Z].
:: However, [Ctrl-A], [Ctrl-F], [Ctrl-M], and [Ctrl-V] will be blocked on Win 10
:: if the console has Ctrl key shortcuts enabled.
::
:: This function works properly regardless whether delayed expansion is enabled
:: or disabled.
::
:: :getKey version 2.0 was written by Dave Benham, and originally posted at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=7396
::
:: This work was inspired by posts from carlos and others at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6382
::
:getKey
setlocal disableDelayedExpansion
if /i "%~1" equ "/P" (
<nul set /p ^"=%2"
shift /1
shift /1
set "getKey./P=1"
) else (
set "getKey./P="
)
:getKeyRetry
(
endlocal&setlocal disableDelayedExpansion
(for /f skip^=1^ delims^=^ eol^= %%A in ('replace.exe ? . /u /w') do for /f delims^=^ eol^= %%B in ("%%A") do (
endlocal
if "%%B" equ "" (set "%1=^!") else set "%1=%%B"
setlocal enableDelayedExpansion
)) || (
endlocal
set "%1="
setlocal enableDelayedExpansion
)
set "getKey./P=%getKey./P%"
if defined %1 (set "getKey.key=!%1!") else set "getKey.key=x"
)
(
if "!%2!" neq "" (
if defined %1 (
set "getKey.mask=!%2:~1!"
if not defined getKey.mask goto :getKeyRetry
if /i "%~3" equ "/I" (
if "!%1!" equ "=" (
set "getKey.mask=a!getKey.mask!"
for /f "delims=" %%A in ("!getKey.mask!") do if /i "!getKey.mask:%%A=%%A!" equ "!getKey.mask!" goto :getKeyRetry
) else for /f delims^=^ eol^= %%A in ("!%1!") do if "!getKey.mask:*%%A=!" equ "!getKey.mask!" goto :getKeyRetry
) else (
for /f tokens^=1*^ eol^=^%getKey.key%^ delims^=^%getKey.key% %%A in ("!getKey.mask!!getKey.mask!") do if "%%B" equ "" goto :getKeyRetry
)
) else if "!%2:~0,1!" equ "0" goto :getKeyRetry
)
if defined getKey./P echo(!%1!
exit /b
)
我想在我的选择命令中添加像 <
|
这样的特殊字符,我该怎么做?
这是我的旧代码:
CHOICE /C ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...."
我希望它是这样的:
CHOICE /C `~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928 /N /M "Press 8 ...."
如有任何帮助,我们将不胜感激。
编辑:因为你们中的一些人可能会问为什么我需要这么多选择,我在这里回答。这是因为按下一个无效的选择会给你一个 annoying 的哔哔声,我不喜欢。所以我问了这个问题。
使用选择,你不能。
如果您尝试使用无效字符执行 Choice,您将收到一条消息。例如(插入符号'^' 符号用于转义管道'|',因为这是cmd 的特殊字符):
CHOICE /C ^|
returns:
错误:无效的选择。有效的选择字符是:a-z、A-Z、0-9 和 128 到 254 的 ASCII 值。
可能的解决方法:
您可以使用 SET 来满足您的需求,但是您在批处理脚本中使用变量可能会导致问题。在任何使用这些变量的地方,都需要以转义字符插入符号 (^) 开头。
此解决方案还需要用户在做出选择后按下回车键。
@ECHO OFF
Choose one:
ECHO.
ECHO ^| - 1
ECHO ^> - 2
ECHO A - 3
ECHO ^" - 4
ECHO ^^ - 5
SET /P KeyPressed=Choice? [^|^>A]
IF [^%KeyPressed%]==[^|] ECHO 1 && GOTO END
IF [^%KeyPressed%]==[^>] ECHO 2 && GOTO END
IF [^%KeyPressed%]==[^A] ECHO 3 && GOTO END
IF [^%KeyPressed%]==[^"] ECHO 4 && GOTO END
IF [^%KeyPressed%]==[^^] ECHO 5 && GOTO END
ECHO None of them.
:END
ShowMenu
Sub ShowHelpMenu
outp.writeline " -----------------------------------------------------------------------------"
outp.writeblanklines(1)
outp.writeline " Menu"
outp.writeline " ----"
outp.writeblanklines(1)
outp.writeline " 1 Help 2 HTML Help 3 Version 4 History"
outp.writeblanklines(1)
outp.writeline " 5 Exit"
outp.writeblanklines(1)
outp.write "Filter>"
End Sub
'=============================================
Sub ShowMenu
Do
ShowHelpMenu
Answ=Inp.readline
If Answ = "1" Then
ShowGeneralHelp "TEXT"
Elseif Answ = "2" Then
ShowGeneralHelp "HTML"
Elseif Answ = "3" Then
Version
Elseif Answ = "4" Then
History
Elseif Answ = "5" Then
Exit Do
End If
Loop
End Sub
Th9is 是一个 VBS 文件。
CHOICE 命令只允许字母数字字符,以及十进制字节代码在 128-254 之间的扩展 ASCII 字符。
我已经基于使用 REPLACE 的 hack 编写了 CHOICE 的纯批处理替代品。我的 :getKey
例程可以接受大多数任何字符,并允许您指定允许的字符,并将捕获的字符放入您选择的变量中 - 比乱用 ERRORLEVEL 方便得多。
我最初将例程发布在 http://www.dostips.com/forum/viewtopic.php?f=3&t=7396。 link 还有一个更复杂的例程,可以绝对读取任何键值,包括 NULL,以及一个允许输入屏蔽字符串(每个字符显示星号)的例程。
下面是 :getKey 例程,以及显示用法的示例。如果您希望按键区分大小写,请移除 /I
开关。脚本中嵌入了完整的文档。
Edit - 我已将代码更新到 2.0 版,能够指定提示,并使有效的键列表区分大小写。 不能 的唯一 CHOICE 功能是带有默认响应的超时选项。我没有看到任何合理的方式来提供超时选项。
@echo off
setlocal enableDelayedExpansion
set "valid=0`~,.<>?ABCDEFGHIJKLMNOPQRSTUVWXYZ0134567928"
call :getKey /p "Press 8 ...." key valid /i
echo(
echo You pressed !key!
exit /b
::getKey [/P "Prompt"] KeyVar [ValidVar [/I]]
::
:: Read a keypress representing a character between 0x00 and 0xFF and store the
:: value in variable KeyVar. Null (0x00), LineFeed (0x0A), and Carriage Return
:: (0x0D) will result in an undefined KeyVar. On Windows 10, Ctrl-Z (0x1A) will
:: also result in an undefined KeyVar. The simplest way to get an undefined
:: KeyVar is to press the [Enter] key.
::
:: The optional /P parameter is used to specify a "Prompt" that is written to
:: stdout, without a newline. Also, the accepted character is ECHOed after the
:: prompt if the /P option was used.
::
:: The optional ValidVar parameter defines the values that will be accepted.
:: If the variable is not given or not defined, then all characters are accepted.
:: If given and defined, then only characters within ValidVar are accepted. The
:: first character within ValidVar should either be 0, meaning ignore undefined
:: KeyVar, or 1, meaning accept undefined KeyVar. The remaining characters
:: represent themselves. For example, a ValidVar value of 0YN will only accept
:: uppercase Y or N. A value of 1YN will additionally accept [Enter] etc.
::
:: If ValidVar is followed by the optional /I switch, then case of standard
:: English letters is ignored. The case of the pressed key is preserved in
:: the result, but English letters A-Z and a-z are not rejected due to case
:: differences when the /I switch is added.
::
:: Any value (except null) may be entered by holding the [Alt] key and pressing
:: the appropriate decimal code on the numeric keypad. For example, holding
:: [Alt] and pressing numeric keypad [1] and [0], and then releasing [Alt] will
:: result in a LineFeed.
::
:: The only way to enter a Null is by holding [Ctrl] and pressing the normal [2]
::
:: An alternate way to enter control characters 0x01 through 0x1A is by holding
:: the [Ctrl] key and pressing any one of the letter keys [A] through [Z].
:: However, [Ctrl-A], [Ctrl-F], [Ctrl-M], and [Ctrl-V] will be blocked on Win 10
:: if the console has Ctrl key shortcuts enabled.
::
:: This function works properly regardless whether delayed expansion is enabled
:: or disabled.
::
:: :getKey version 2.0 was written by Dave Benham, and originally posted at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=7396
::
:: This work was inspired by posts from carlos and others at
:: http://www.dostips.com/forum/viewtopic.php?f=3&t=6382
::
:getKey
setlocal disableDelayedExpansion
if /i "%~1" equ "/P" (
<nul set /p ^"=%2"
shift /1
shift /1
set "getKey./P=1"
) else (
set "getKey./P="
)
:getKeyRetry
(
endlocal&setlocal disableDelayedExpansion
(for /f skip^=1^ delims^=^ eol^= %%A in ('replace.exe ? . /u /w') do for /f delims^=^ eol^= %%B in ("%%A") do (
endlocal
if "%%B" equ "" (set "%1=^!") else set "%1=%%B"
setlocal enableDelayedExpansion
)) || (
endlocal
set "%1="
setlocal enableDelayedExpansion
)
set "getKey./P=%getKey./P%"
if defined %1 (set "getKey.key=!%1!") else set "getKey.key=x"
)
(
if "!%2!" neq "" (
if defined %1 (
set "getKey.mask=!%2:~1!"
if not defined getKey.mask goto :getKeyRetry
if /i "%~3" equ "/I" (
if "!%1!" equ "=" (
set "getKey.mask=a!getKey.mask!"
for /f "delims=" %%A in ("!getKey.mask!") do if /i "!getKey.mask:%%A=%%A!" equ "!getKey.mask!" goto :getKeyRetry
) else for /f delims^=^ eol^= %%A in ("!%1!") do if "!getKey.mask:*%%A=!" equ "!getKey.mask!" goto :getKeyRetry
) else (
for /f tokens^=1*^ eol^=^%getKey.key%^ delims^=^%getKey.key% %%A in ("!getKey.mask!!getKey.mask!") do if "%%B" equ "" goto :getKeyRetry
)
) else if "!%2:~0,1!" equ "0" goto :getKeyRetry
)
if defined getKey./P echo(!%1!
exit /b
)