Batch file 从批处理文件中的单词列表中搜索特定单词
我有一个Batch file 从批处理文件中的单词列表中搜索特定单词,batch-file,cmd,scripting,Batch File,Cmd,Scripting,我有一个%list%变量,该变量包含单词(请参见代码),我希望搜索以字母“Y”结尾的单词(忽略区分大小写),并以用户输入的最后一个字母开头。用户输入将是任何有效的单词。找到特定单词后,我想将其存储到变量中(%myWord%)。我打算稍后在代码中使用%myWord%变量。如果我已经使用了%list%中的那个词,那么我希望向用户显示一个新词。我的单词列表以任意字母开头,以“Y”字母结尾,并按字母顺序排列。%list%相当长。 下面是我的代码。我觉得我迷路了,找不到解决这个问题的办法 @echo of
%list%
变量,该变量包含单词(请参见代码),我希望搜索以字母“Y”结尾的单词(忽略区分大小写),并以用户输入的最后一个字母开头。用户输入将是任何有效的单词。找到特定单词后,我想将其存储到变量中(%myWord%
)。我打算稍后在代码中使用%myWord%
变量。如果我已经使用了%list%
中的那个词,那么我希望向用户显示一个新词。我的单词列表以任意字母开头,以“Y”字母结尾,并按字母顺序排列。%list%
相当长。
下面是我的代码。我觉得我迷路了,找不到解决这个问题的办法
@echo off
:START
set /p INPUTWORD=>Enter a word:
SET lastletter=%INPUTWORD:~-1%
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
For %%L in (%list%) do (
SET endingY=%%L:~-1%
For %%X in (a b c d e f g h i j k l m n o p q r s t u v w x y z) do (
if findstr /i "%lastletter%" %%X EQU first letter of the words in %list%
if %%L:~-1% EQU "y"
if %myWord% is already shown to user then search for a new word.
and then set myWord==%%L (new word; unused one)
echo My Word is: %myWord%
pause
goto START
例如:
第1场会议:
输入一个单词:dog
我的话是:很高兴
第2次会议:
输入一个单词:yak
我的话是:钥匙
使用任何类型的函数都完全可以。只要它能找到合适的词。
这似乎是可能的,但我已经厌倦了思考。我想我可能需要新鲜一点。你的描述是错误的。它说:“我想搜索一个以字母‘Y’结尾、以用户输入的第一个字母开头的单词”,但代码会查找一个以用户输入的最后一个字母开头的单词。下面我的解决方案使用代码规范
@echo off
setlocal EnableDelayedExpansion
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
:START
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD goto :EOF
rem Get last letter of user's input
SET lastLetter=%INPUTWORD:~-1%
rem For each word in the list...
For %%L in (%list%) do (
rem Store the word in "myWord" variable
set "myWord=%%L"
rem If the word starts with the last letter of user's input
rem and ends with letter 'Y' (ignoring the case-sensitive)
if /I "!myWord:~0,1!!myWord:~-1!" equ "%lastLetter%Y" (
rem Remove the already used word from the list
rem so the next time, a new word be shown to user
set "list=!list:%%L=!"
rem And break the FOR loop, because the word was found
goto break
)
)
rem If all words in the list was reviewed, indicate that the word was not found
set "myWord=Word not found in list"
:break
echo My Word is: %myWord%
pause
goto START
关于这个问题的几点观察:
- 如果所有单词都以“Y”字母结尾,则无需检查此点(“单词以“Y”结尾”)
- 单词按字母顺序排列没有任何好处。无论如何,除非开发出更复杂的方法,否则需要对整个列表进行审查,以搜索目标词
- 您的描述是错误的。它说:“我想搜索一个以字母‘Y’结尾、以用户输入的第一个字母开头的单词”,但代码会查找一个以用户输入的最后一个字母开头的单词。下面我的解决方案使用代码规范
@echo off
setlocal EnableDelayedExpansion
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
:START
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD goto :EOF
rem Get last letter of user's input
SET lastLetter=%INPUTWORD:~-1%
rem For each word in the list...
For %%L in (%list%) do (
rem Store the word in "myWord" variable
set "myWord=%%L"
rem If the word starts with the last letter of user's input
rem and ends with letter 'Y' (ignoring the case-sensitive)
if /I "!myWord:~0,1!!myWord:~-1!" equ "%lastLetter%Y" (
rem Remove the already used word from the list
rem so the next time, a new word be shown to user
set "list=!list:%%L=!"
rem And break the FOR loop, because the word was found
goto break
)
)
rem If all words in the list was reviewed, indicate that the word was not found
set "myWord=Word not found in list"
:break
echo My Word is: %myWord%
pause
goto START
关于这个问题的几点观察:
- 如果所有单词都以“Y”字母结尾,则无需检查此点(“单词以“Y”结尾”)
- 单词按字母顺序排列没有任何好处。无论如何,除非开发出更复杂的方法,否则需要对整个列表进行审查,以搜索目标词
- 您的描述是错误的。它说:“我想搜索一个以字母‘Y’结尾、以用户输入的第一个字母开头的单词”,但代码会查找一个以用户输入的最后一个字母开头的单词。下面我的解决方案使用代码规范
@echo off
setlocal EnableDelayedExpansion
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
:START
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD goto :EOF
rem Get last letter of user's input
SET lastLetter=%INPUTWORD:~-1%
rem For each word in the list...
For %%L in (%list%) do (
rem Store the word in "myWord" variable
set "myWord=%%L"
rem If the word starts with the last letter of user's input
rem and ends with letter 'Y' (ignoring the case-sensitive)
if /I "!myWord:~0,1!!myWord:~-1!" equ "%lastLetter%Y" (
rem Remove the already used word from the list
rem so the next time, a new word be shown to user
set "list=!list:%%L=!"
rem And break the FOR loop, because the word was found
goto break
)
)
rem If all words in the list was reviewed, indicate that the word was not found
set "myWord=Word not found in list"
:break
echo My Word is: %myWord%
pause
goto START
关于这个问题的几点观察:
- 如果所有单词都以“Y”字母结尾,则无需检查此点(“单词以“Y”结尾”)
- 单词按字母顺序排列没有任何好处。无论如何,除非开发出更复杂的方法,否则需要对整个列表进行审查,以搜索目标词
- 您的描述是错误的。它说:“我想搜索一个以字母‘Y’结尾、以用户输入的第一个字母开头的单词”,但代码会查找一个以用户输入的最后一个字母开头的单词。下面我的解决方案使用代码规范
@echo off
setlocal EnableDelayedExpansion
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
:START
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD goto :EOF
rem Get last letter of user's input
SET lastLetter=%INPUTWORD:~-1%
rem For each word in the list...
For %%L in (%list%) do (
rem Store the word in "myWord" variable
set "myWord=%%L"
rem If the word starts with the last letter of user's input
rem and ends with letter 'Y' (ignoring the case-sensitive)
if /I "!myWord:~0,1!!myWord:~-1!" equ "%lastLetter%Y" (
rem Remove the already used word from the list
rem so the next time, a new word be shown to user
set "list=!list:%%L=!"
rem And break the FOR loop, because the word was found
goto break
)
)
rem If all words in the list was reviewed, indicate that the word was not found
set "myWord=Word not found in list"
:break
echo My Word is: %myWord%
pause
goto START
关于这个问题的几点观察:
- 如果所有单词都以“Y”字母结尾,则无需检查此点(“单词以“Y”结尾”)
- 单词按字母顺序排列没有任何好处。无论如何,除非开发出更复杂的方法,否则需要对整个列表进行审查,以搜索目标词
y
结尾,因为您的列表只包含以y
结尾的单词
此解决方案假定列表中的所有单词至少有两个字母
@echo off
setlocal EnableDelayedExpansion
:: The list must start and end with a space, the word order does not matter
set "list= daddy day gladly happily key pay randomly ray say urgency utility yesterday "
:start
echo(
:: Exit if list is empty (nothing but spaces)
if "%list: =%" equ "" (
echo No more words in list
exit /b
)
:: Get the users input, exit if none
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD exit /b
:: Look for the first word that begins with the last letter of the input
:: and delete everything up through the first letter of the matching word
set "test=!list:* %INPUTWORD:~-1%=!"
:: If the modified list matches the original, then no word was found.
:: Give message and try again
if "%test%" equ "%list%" (
echo myWord not found
goto :start
)
:: Get the remainder of the word and rebuild the complete word
for %%W in (%test%) do (
set "myWord=%INPUTWORD:~-1%%%W"
goto :break
)
:break
:: Remove the word from the list
set "list=!list: %myWord% = !"
:: Show the result and loop back
echo myWord=%myWord%
goto :start
代码注释中包含的解释 这看起来可能有很多代码,但实际上相当有效 无需验证找到的单词是否以
y
结尾,因为您的列表只包含以y
结尾的单词
此解决方案假定列表中的所有单词至少有两个字母
@echo off
setlocal EnableDelayedExpansion
:: The list must start and end with a space, the word order does not matter
set "list= daddy day gladly happily key pay randomly ray say urgency utility yesterday "
:start
echo(
:: Exit if list is empty (nothing but spaces)
if "%list: =%" equ "" (
echo No more words in list
exit /b
)
:: Get the users input, exit if none
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD exit /b
:: Look for the first word that begins with the last letter of the input
:: and delete everything up through the first letter of the matching word
set "test=!list:* %INPUTWORD:~-1%=!"
:: If the modified list matches the original, then no word was found.
:: Give message and try again
if "%test%" equ "%list%" (
echo myWord not found
goto :start
)
:: Get the remainder of the word and rebuild the complete word
for %%W in (%test%) do (
set "myWord=%INPUTWORD:~-1%%%W"
goto :break
)
:break
:: Remove the word from the list
set "list=!list: %myWord% = !"
:: Show the result and loop back
echo myWord=%myWord%
goto :start
代码注释中包含的解释 这看起来可能有很多代码,但实际上相当有效 无需验证找到的单词是否以
y
结尾,因为您的列表只包含以y
结尾的单词
此解决方案假定列表中的所有单词至少有两个字母
@echo off
setlocal EnableDelayedExpansion
:: The list must start and end with a space, the word order does not matter
set "list= daddy day gladly happily key pay randomly ray say urgency utility yesterday "
:start
echo(
:: Exit if list is empty (nothing but spaces)
if "%list: =%" equ "" (
echo No more words in list
exit /b
)
:: Get the users input, exit if none
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD exit /b
:: Look for the first word that begins with the last letter of the input
:: and delete everything up through the first letter of the matching word
set "test=!list:* %INPUTWORD:~-1%=!"
:: If the modified list matches the original, then no word was found.
:: Give message and try again
if "%test%" equ "%list%" (
echo myWord not found
goto :start
)
:: Get the remainder of the word and rebuild the complete word
for %%W in (%test%) do (
set "myWord=%INPUTWORD:~-1%%%W"
goto :break
)
:break
:: Remove the word from the list
set "list=!list: %myWord% = !"
:: Show the result and loop back
echo myWord=%myWord%
goto :start
代码注释中包含的解释 这看起来可能有很多代码,但实际上相当有效 无需验证找到的单词是否以
y
结尾,因为您的列表只包含以y
结尾的单词
此解决方案假定列表中的所有单词至少有两个字母
@echo off
setlocal EnableDelayedExpansion
:: The list must start and end with a space, the word order does not matter
set "list= daddy day gladly happily key pay randomly ray say urgency utility yesterday "
:start
echo(
:: Exit if list is empty (nothing but spaces)
if "%list: =%" equ "" (
echo No more words in list
exit /b
)
:: Get the users input, exit if none
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD exit /b
:: Look for the first word that begins with the last letter of the input
:: and delete everything up through the first letter of the matching word
set "test=!list:* %INPUTWORD:~-1%=!"
:: If the modified list matches the original, then no word was found.
:: Give message and try again
if "%test%" equ "%list%" (
echo myWord not found
goto :start
)
:: Get the remainder of the word and rebuild the complete word
for %%W in (%test%) do (
set "myWord=%INPUTWORD:~-1%%%W"
goto :break
)
:break
:: Remove the word from the list
set "list=!list: %myWord% = !"
:: Show the result and loop back
echo myWord=%myWord%
goto :start
这种解决方案应该是最有效的方法,因为它根据单词的第一个字母将原始列表拆分为子列表。这样,通过
if defined子列表[%lastLetter%]
立即测试某个单词是否存在,并在更短的变量中提取该单词。此外,由于代码的大小,此方法是明确的
@echo off
setlocal EnableDelayedExpansion
set "list=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
rem Split the list in sub-lists (an array) based on the first letter of the words
for %%w in (%list%) do (
set "word=%%w"
for /F %%l in ("!word:~0,1!") do set "subList[%%l]=!subList[%%l]! %%w"
)
ECHO CONTENTS OF THE SUB-LISTS:
SET SUBLIST
ECHO/
:START
set "INPUTWORD="
set /p "INPUTWORD=>Enter a word: "
if not defined INPUTWORD goto :EOF
rem Get last letter of user's input
SET lastLetter=%INPUTWORD:~-1%
rem If a sub-list for that letter exists...
if defined subList[%lastLetter%] (
rem Extract the first word from such sub-list
for /F "tokens=1*" %%a in ("!subList[%lastLetter%]!") do (
set "myWord=%%a"
set "subList[%lastLetter%]=%%b"
)
) else (
set "myWord=Word not found in list"
)
echo My Word is: %myWord%
echo/
goto START
示例会话:
CONTENTS OF THE SUB-LISTS:
subList[d]= daddy day
subList[g]= gladly
subList[h]= happily
subList[k]= key
subList[p]= pay
subList[r]= randomly ray
subList[s]= say
subList[u]= urgency utility
subList[y]= yesterday
>Enter a word: dog
My Word is: gladly
>Enter a word: yak
My Word is: key
>Enter a word: dad
My Word is: daddy
>Enter a word: dad
My Word is: day
>Enter a word: dad
My Word is: Word not found in list
>Enter a word:
有关批处理中阵列的进一步说明,请参阅
编辑:我试图在我的解决方案与dbenham的解决方案之间实施一个计时测试,但我无法完成它
@echo off
setlocal EnableDelayedExpansion
set "list0=daddy day gladly happily key pay randomly ray say urgency utility yesterday"
rem Create the initial list repeating the previous "list0" 100 times (= 1200 words)
rem changing the initial letter by a random one
echo Creating initial list...
set "letter=abcdefghijklmnopqrstuvwxyz"
set "list="
for /L %%t in (1,1,100) do (
for %%a in (%list0%) do (
set "word=%%a"
set /A i=!random! %% 26
for /F %%i in ("!i!") do set "list=!list! !letter:~%%i,1!!word:~1!"
)
)
rem ========================
echo Testing Aacini's
rem Start Aacini's code test
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
set /A "H=%%a, M=1%%b%%100, S=1%%c%%100, startA=(H*60+M)*60+S"
)
rem Split the list in sub-lists (an array) based on the first letter of the words
for %%w in (%list%) do (
set "word=%%w"
for /F %%l in ("!word:~0,1!") do set "subList[%%l]=!subList[%%l]! %%w"
)
rem Get 1000 words selecting a random last letter
for /L %%? in (1,1,1000) do (
set /A i=!random! %% 26
for /F %%i in ("!i!") do SET "lastLetter=!letter:~%%i,1!"
rem If a sub-list for that letter exists...
if defined subList[!lastLetter!] (
rem Extract the first word from such sub-list
for /F %%L in ("!lastLetter!") do for /F "tokens=1*" %%a in ("!subList[%%L]!") do (
set "myWord=%%a"
set "subList[%%L]=%%b"
)
) else (
set "myWord=Word not found in list"
)
echo %%?- My Word is: !myWord!
REM echo/
REM goto START
)
rem End Aacini's code test
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
set /A "H=%%a, M=1%%b%%100, S=1%%c%%100, endA=(H*60+M)*60+S"
)
rem ========================
echo Testing dbenham's
rem Start dbenham's code test
:: The list must start with dot space and end with space dot, the word order does not matter
set "list=. %list% ."
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
set /A "H=%%a, M=1%%b%%100, S=1%%c%%100, startD=(H*60+M)*60+S"
)
rem Get 1000 words selecting a random last letter
for /L %%? in (1,1,1000) do (
set /A i=!random! %% 26
for /F %%i in ("!i!") do SET "LastLetter=!letter:~%%i,1!"
REM :start
REM echo(
Rem Exit if list is empty
if "!list: =!" equ ".." (
echo No more words in list
goto endDbenham
)
Rem Iterate value of list after replacing "<space>%LastLetter%" with "<newLine>%LastLetter%".
Rem Skip the first line and take the first token, which will be myWord.
Rem If no substitution, then only one line so DO will not fire.
Rem The empty line below (after the FOR line^) is critical - DO NO REMOVE
set "break="
for /F %%L in ("!LastLetter!") do for /f "usebackq skip=1" %%W in ('!list: %%L^=^
%%L!') do if not defined break (
REM remove myWord from the list
set "list=!list: %%W = !"
REM show result and loop back for more (breaks out of loop^)
echo %%?- myWord = %%W
REM goto :start
set "break=Yes"
)
if not defined break (
Rem Only reaches here if myWord not found
echo %%?- myWord not found
REM goto :start
)
)
rem =======================
:endDbenham
rem End dbenham's code test
for /F "tokens=1-3 delims=:." %%a in ("%time%") do (
set /A "H=%%a, M=1%%b%%100, S=1%%c%%100, endD=(H*60+M)*60+S"
)
set /A elapsedA=endA-startA, elapsedD=endD-startD
echo/
echo Aacini's: %elapsedA% seconds
echo dbenham's: %elapsedD% seconds
@echo关闭
setlocal EnableDelayedExpansion
设置“list0=爸爸节快乐快乐键随机支付ray昨天说的紧急实用程序”
rem创建初始列表,重复上一个“list0”100次(=1200字)
rem将首字母更改为随机字母
回声创建初始值