[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] 【已解决】求助批处理辨别用户输入的内容是否符合某个规范

本帖最后由 蚯蚓传奇 于 2024-8-21 12:04 编辑

我想请教一下怎么辨别用户输入一段日期是否符合规范
让用户输入一个日期,然后程序检查文本是否是按照**(月)/**(日)的格式写的
如果可以的话,我还想让这个程序拥有检查日期是否有错误的功能,比如1月不能有31号
最好只用批处理或者powershell,谢谢
1

评分人数

    • Batcher: 感谢给帖子标题标注[已解决]字样PB + 2

本帖最后由 aloha20200628 于 2024-8-19 17:17 编辑

回复 1# 蚯蚓传奇

以下代码存为 test.bat 运行...
备注》powershell兼容 ‘月/日’ 和 ‘月-日’ 多种格式分隔符,自动检查月日合法性(尤其是2月日期)
  1. @echo off &set/p "_md=输入日期(月值/日值):"
  2. for /f %%v in (
  3. 'powershell "('2024/%_md%' -as [DateTime]) -ne $null" '
  4. ) do if /i "%%v"=="true" (echo,输入合法) else (echo,输入非法)
  5. pause&exit/b
复制代码
1

评分人数

TOP

回复 2# aloha20200628


    感谢分享,我刚才试了这段代码,你判断日期是否合法的那段代码我已经采纳了,可是我主要是想让他判断格式是否符合**/**,不知道能不能实现

TOP

本帖最后由 aloha20200628 于 2024-8-19 21:10 编辑

回复 3# 蚯蚓传奇

增添子过程 :xxx 用于检查日期输入格式是否满足 mm/dd,分隔符须为 /,mm 和 dd 都必须是两位数字...
  1. @echo off &setlocal &set/p "md=输入日期(月值/日值):"
  2. call :xxx "%md%"
  3. if %ok% equ 0 (echo,输入非法)&exit/b
  4. for /f %%v in (
  5. 'powershell "('2024/%md%' -as [DateTime]) -ne $null" '
  6. ) do if /i "%%v"=="true" (echo,输入合法) else (echo,输入非法)
  7. endlocal&pause&exit/b
  8. :xxx
  9. set "v=%~1" &set "ok=0" &set "n="
  10. if "%v:~4,1%" neq "" if "%v:~5%"=="" (
  11. for /f "delims=0123456789/" %%n in ("%~1") do set "n=1"
  12. if not defined n set "ok=1"
  13. )
  14. exit/b
复制代码
1

评分人数

TOP

  1. set /p "dt=Input:"
  2. PowerShell "$out=0; [DateTime]::TryParseExact('%dt%', 'M/d', [Globalization.CultureInfo]'zh-CN', [Globalization.DateTimeStyles]::None, [ref]$out)"
复制代码

TOP

本帖最后由 ppll2030 于 2024-8-20 13:22 编辑

回复 3# 蚯蚓传奇


    在第一和第二行之间,加一句代码即可,有且仅对日期格式判断
  1. echo %_md%|findstr /x "[0-1][0-9]/[0-3][0-9]">nul||(echo 日期格式不正确&pause&exit /b)
复制代码
把日期对错也一并加入判断了。一次性完成日期对错和日期格式的判断。
  1. @echo off
  2. set/p "_md=输入日期(月值/日值):"
  3. echo %_md%|findstr /x "0[1-9]/0[1-9] 0[1-9]/[1-2][0-9] 0[13578]/3[0-1] 0[469]/30 1[0-2]/0[1-9] 1[0-2]/[1-2][0-9] 1[02]/3[0-1] 11/30">nul||set "v=不"
  4. echo 日期输入%v%正确!&pause&exit/b
复制代码
1

评分人数

TOP

  1. @echo off
  2. set /p str=input:
  3. call :1
  4. if defined k (
  5. echo 合法
  6. ) else (
  7. echo 非法
  8. )
  9. pause
  10. exit
  11. :1
  12. setlocal
  13. for /f %%a in ('wmic os get localdatetime ^|findstr [0-9]') do set year=%%a&call set year=%%year:~0,4%%
  14. set /a _1=_3=_5=_7=_8=_10=_12=31,_4=_6=_9=_11=30
  15. rem "http://www.bathome.net/redirect.php?goto=findpost&ptid=3769&pid=24349"
  16. set/a num=!(year%%4) ^& !(!(year%%100)) ^| !(year%%400),1/num 2>nul && set _2=29|| set _2=28
  17. setlocal enabledelayedexpansion
  18. for /l %%l in (1,1,12) do for /l %%m in (1,1,!_%%l!) do (set l=0%%l&set m=0%%m&set #!l:~-2!/!m:~-2!=1)
  19. if defined #!str! (endlocal &endlocal &set k=1) else (endlocal &endlocal)
  20. exit /b
复制代码
1

评分人数

bat小白,请多指教!谢谢!

TOP

本帖最后由 aloha20200628 于 2024-8-24 22:32 编辑


参考6楼代码用 findstr 小正则卡位定界 mm/dd 格式输入,句式更为简洁,如此4楼代码可减肥‘到底’ ,给出如下两个等效版本...

第一版本》先行正则卡位定界,再行powershell合法性检查
  1. @echo off &setlocal &set/p "md=输入日期(月值/日值):"
  2. echo,%md%|findstr /rc:"[01][0-9]/[0-3][0-9]">nul||echo,非法&endlocal&pause&exit/b
  3. powershell "('2024/%md%' -as [DateTime]) -ne $null"|find /i "true">nul
  4. if errorlevel 1 (echo,非法) else (echo,合法)
  5. endlocal&pause&exit/b
复制代码
第二版本》先行powershell合法性检查,再行卡位定界
  1. @echo off &setlocal &set "w=非法" &set/p "md=输入日期(月值/日值):"
  2. powershell "('2024/%md%' -as [DateTime]) -ne $null"|find /i "true">nul
  3. if errorlevel 1 (set k=1) else if "%md:~2,1%"=="/" if "%md:~-3,1%"=="/" set "w=合法"
  4. echo,%w%&endlocal&pause&exit/b
复制代码

TOP

回复 6# ppll2030


    谢谢分享,可以用,而且效率很高

TOP

本帖最后由 77七 于 2024-8-20 11:00 编辑

echo 一个未知的字符串|find (findstr)其实是一个很危险的操作,因为特殊字符影响会导致各种错误
  1. @echo off
  2. set "str=1&2"
  3. echo %str%|find "1" 1>nul && echo #1 闪退
  4. echo %str%|find "2" 1>nul && echo #2 闪退
  5. echo "%str%"|find "1" 1>nul && echo #3 判断成功
  6. echo "%str%"|find "2" 1>nul && echo #4 判断成功
  7. setlocal enabledelayedexpansion
  8. echo !str!|find "1" 1>nul && echo #5 报错,判断成功
  9. echo !str!|find "2" 1>nul && echo #6 报错,判断失败
  10. set "str=1&2""
  11. echo "%str%"|find "1" 1>nul && echo #7 整行的特殊符号都被双引号转义
  12. pause
复制代码
1

评分人数

bat小白,请多指教!谢谢!

TOP

简单、方便、准确,让神马的 for 和 if 见鬼去吧。
  1. $myInput  = Read-Host 'Input';
  2. $formats  = [String[]]('MM/dd', 'M/d');
  3. $provider = [Globalization.CultureInfo]'zh-CN';
  4. $style    = [Globalization.DateTimeStyles]::None;
  5. $result   = [DateTime]0;
  6. [DateTime]::TryParseExact($myInput, $formats, $provider, $style, [ref]$Result);
  7. [Console]::ReadLine()
复制代码
https://learn.microsoft.com/zh-cn/dotnet/api/system.datetime.tryparseexact?view=net-8.0
1

评分人数

TOP

本帖最后由 aloha20200628 于 2024-8-20 17:06 编辑

回复 10# 77七

‘纯P老窖’ 还留了一款  set/p="..."<nul  此时正好派上用场...
echo,"..." 连双引号一并输出;而 set/p="..."<nul 只输出双引号包裹的内容,但先戴上双引号即可免遭 ‘雷劈’
  1. set/p="1&2"<nul|find "1">nul&&echo,#1
  2. set/p="1&2"<nul|find "2">nul&&echo,#2
复制代码

TOP

回复 6# ppll2030
回复 9# 蚯蚓传奇

网查用正则匹配(同时也是检查)日期格式有多种杂乱版本,实测了一把6楼代码,发现有一处须予订正如下,否则会漏检 10/00,11/00,12/00 的错误:

   旧码》findstr /x "0[1-9]/0[1-9] 0[1-9]/[1-2][0-9] 0[13578]/3[0-1] 0[469]/30 1[0-2]/0[0-9] 1[0-2]/[1-2][0-9] 1[02]/3[0-1] 11/30"
   新码》findstr /x "0[1-9]/0[1-9] 0[1-9]/[1-2][0-9] 0[13578]/3[0-1] 0[469]/30 1[0-2]/0[1-9] 1[0-2]/[1-2][0-9] 1[02]/3[0-1] 11/30"

另注》仅用正则匹配不能兼顾平/闰年2月增减天数的变化,还须增添代码修正...

TOP

回复 12# aloha20200628


  set /p="..."<nul 对比echo "..."优点不多,缺点倒是多一些
bat小白,请多指教!谢谢!

TOP

回复 13# aloha20200628


    感谢大佬指正~!
大半夜想这些烧脑的东西,效率还是低了。

TOP

返回列表