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

回复 45# aloha20200628
1//1a
1/--1
1/+1
一个是分隔符被忽略的问题,一个是if比较时不能转换成有效数字的会按字符比较,数字比较时没有排除正负号。
忘了还有变量延迟下的两个特殊字符,
1/!1
1/!^1

TOP

本帖最后由 77七 于 2024-8-24 18:29 编辑
  1. @echo off
  2. for /f %%a in ('wmic os get localdatetime ^|findstr [0-9]') do set year=%%a&call set year=%%year:~0,4%%
  3. set /a _1=_3=_5=_7=_8=_10=_12=31,_4=_6=_9=_11=30
  4. set/a num=!(year%%4) ^& !(!(year%%100)) ^| !(year%%400),1/num 2>nul && set _2=29|| set _2=28
  5. :loop
  6. setlocal
  7. set /p n=input:
  8. set "n1=%n:~0,2%"
  9. set "n2=%n:~2,1%"
  10. set "n3=%n:~3,2%"
  11. set "n4=%n:~5%"
  12. setlocal enabledelayedexpansion
  13. set a=非法
  14. if "!n2!" equ "/" (
  15. if "!n4!" equ "" (
  16. for /l %%l in (1,1,12) do (
  17. set str=0%%l
  18. if "!n1!" equ "!str:~-2!" (
  19. for /l %%m in (1,1,!_%%l!) do (
  20. set str=0%%m
  21. if "!n3!" equ "!str:~-2!" (
  22. set a=合法
  23. )
  24. )
  25. )
  26. )
  27. )
  28. )
  29. endlocal & endlocal &echo %a%
  30. goto :loop
复制代码

判断 相应位置的字符串与 分隔符号 "/" 及限定范围的日期、月份是否有相等情况。初步测试,可以应付各种特殊字符。
bat小白,请多指教!谢谢!

TOP

简化一下
  1. @echo off
  2. for /f %%a in ('wmic os get localdatetime ^|findstr [0-9]') do set year=%%a&call set year=%%year:~0,4%%
  3. set /a _1=_3=_5=_7=_8=_10=_12=31,_4=_6=_9=_11=30
  4. set/a num=!(year%%4) ^& !(!(year%%100)) ^| !(year%%400),1/num 2>nul && set _2=29|| set _2=28
  5. :loop
  6. setlocal
  7. set /p n=input:
  8. setlocal enabledelayedexpansion
  9. set a=非法
  10. if "!n:~2,1!!n:~5,1!" equ "/" (
  11. for /l %%l in (1,1,12) do (
  12. set str=0%%l
  13. if "!n:~0,2!" equ "!str:~-2!" (
  14. for /l %%m in (1,1,!_%%l!) do (
  15. set str=0%%m
  16. if "!n:~3,2!" equ "!str:~-2!" (
  17. set a=合法
  18. )
  19. )
  20. )
  21. )
  22. )
  23. endlocal & endlocal &echo %a%
  24. goto :loop
复制代码
bat小白,请多指教!谢谢!

TOP

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

回复 46# buyiyang

45楼代码已订正,堵上了被多种 ‘怪异字符’ 轰击破防的缺口...

本帖歇后语》不用外部方法援助,不用正则匹配简化,感觉纯P自力更生的造码能力还可以...而真正的着力点落在了应对预处理和防止怪异字符的雷劈...

TOP

回复 45# aloha20200628

endlcoal 后第二行设定的变量也无了,
第14行的if %m% lss 1 if %m% gtr 12 逻辑有误,其实这一行不要也行,第17行if %d% gtr 0 if %d% leq !%_m%! 兼有限制月份的作用。

TOP

本帖最后由 aloha20200628 于 2024-8-24 21:02 编辑

回复 50# buyiyang
谢谢细心测试 45楼代码已被订正...
要纯P到底,那些 卡位,定界,全数字核查... 一点懒儿都不能偷

TOP

本帖最后由 buyiyang 于 2024-8-25 12:47 编辑

综合一下35、45、48、55楼,有一些不错的写法
最终主体只需要9、11、12行三句判断就够了。
第9行限制输入字符数和分隔符位置,
第11行限制月份和日期均为数字,
第12行限制月份和日期范围。
  1. @echo off
  2. for /f "tokens=2" %%i in ('wmic os get codeset^,localdatetime') do set yyyy=%%i&call set yyyy=%%yyyy:~0,4%%
  3. set /a _01=_03=_05=_07=_08=_10=_12=31,_04=_06=_09=_11=30,"_02=28+(!(yyyy%%4)&!!(yyyy%%100)|!(yyyy%%400))"
  4. set "error=echo,Invalid date&endlocal&goto :loop"
  5. :loop
  6. set /p "md=Please enter a date (MM/DD):"
  7. setlocal enabledelayedexpansion
  8. if "!md:~2,-2!" neq "/" (%error%)
  9. set "mm=!md:~0,2!"&set "dd=!md:~3,2!"
  10. for /f "delims=0123456789" %%i in ("!mm!!dd!") do (%error%)
  11. if "!dd!" gtr "00" if "!dd!" leq "!_%mm%!" (echo,Valid date&endlocal&goto :loop)
  12. %error%
复制代码
1

评分人数

    • 77七: 感谢分享技术 + 1

TOP

回复 45# aloha20200628

大佬,感觉应对特殊字符还是开启延迟变量扩展专业,如第7、8行无法处理 双引号
bat小白,请多指教!谢谢!

TOP

本帖最后由 aloha20200628 于 2024-8-24 23:26 编辑

回复 53# 77七

谢谢 代码已订正... 但愿是最后一把 ‘堵漏灵’...
从8楼调用 powershell+findstr 外援的4-5行代码到45楼的纯P自力更生版,已经垒起21行代码了,要经得起各种怪异字符的 ‘雷劈’ ... 纯粹是要过把瘾的一套脑力操...

TOP

本帖最后由 qixiaobin0715 于 2024-8-25 10:39 编辑

不包括修改代码,我也发上来过两版代码,就是漏洞太多。总体感觉是,不能自我陶醉,沾沾自喜,总是觉得自己的代码思路好,完美无缺,实际上还差得远着呢,低调最重要。
不怕大家笑话,再来一版,希望大佬们批评指正。还是限定输入格式为:01/01这样的。
下面代码的前一部分还是主要借鉴了27楼的思路。原则上尽量少预设变量(29楼代码开始预设了几十个变量,主要是便于后面进行判断,可能会影响一些效率)。第6行判断语句既定位了“/”字符,又能限定输入的字符长度为5,一举两得,主要还是得益于aloha20200628的提醒:
  1. @echo off
  2. setlocal enabledelayedexpansion
  3. :o
  4. set/p "md=Please Input the Date (MM/DD):"
  5. set "mm/dd=!md!"
  6. if "!mm/dd:~2,-2!"=="/" (
  7.     if "!mm/dd:00=!"=="!mm/dd!" (
  8.         for /l %%i in (0,1,9) do set "mm/dd=!mm/dd:%%i=!"
  9.         if "!mm/dd!"=="/" set n=1
  10.     )
  11. )
  12. if not defined n goto :p
  13. for /f "tokens=1* delims=/" %%i in ("!md!") do (
  14.     if %%i gtr 12 (set n=) else if %%j gtr 31 (set n=)
  15.     if defined n (
  16.         if %%j equ 30 (
  17.             if %%i equ 2 set n=
  18.         ) else if %%j equ 31 (
  19.             for %%k in (02 04 06 09 11) do if %%k equ %%i set n=
  20.         )
  21.     )
  22. )
  23. :p
  24. if defined n (echo,Input Correct) else (echo,Input Error&goto :o)
  25. pause
复制代码
另外,改变一下输入格式。合法:1/2  1/31  01/02  01/31  12/01  12/1,非法:01/2  1/01。如何才能判断?
2

评分人数

    • buyiyang: "!mm/dd:~2,-2!"=="/"技术 + 1
    • 77七: 感谢分享技术 + 1

TOP

回复 55# qixiaobin0715


   大佬,您最后提出的新问题,我没看懂...
bat小白,请多指教!谢谢!

TOP

本帖最后由 qixiaobin0715 于 2024-8-25 12:03 编辑

回复 56# 77七
我的失误,没有表达清楚。有人习惯月份日期是个位数时前面加个0,都变成两位数;有人不习惯加0补位,直接写。我要表达的是,两种不能混合写,比如1月1日,要么写成01/01或者1/1,而不能写成01/1或1/01。

TOP

回复 55# qixiaobin0715


   大佬,我觉得几十个变量不会影响效率。尤其类似的简短变量 set #01=01,试着定义了5000个,耗时1秒左右,然后判断是否定义,echo %time%对比了下,时间相同。
  1. 12:07:14.02
  2. 12:07:15.26
  3. 1
  4. 12:07:15.26
复制代码


分别为定义开始时间、结束时间、判断是否被定义时间
bat小白,请多指教!谢谢!

TOP

本帖最后由 buyiyang 于 2024-8-25 12:32 编辑

回复 55# qixiaobin0715


    我尝试写了一个
  1. @echo off
  2. for /f "tokens=2" %%i in ('wmic os get codeset^,localdatetime') do set yyyy=%%i&call set yyyy=%%yyyy:~0,4%%
  3. set /a _01=_03=_05=_07=_08=_10=_12=31,_04=_06=_09=_11=30,"_02=28+(!(yyyy%%4)&!!(yyyy%%100)|!(yyyy%%400))"
  4. set "error=echo,Invalid date&endlocal&goto :loop"
  5. :loop
  6. set /p "md=Please enter a date (M/D):"
  7. setlocal enabledelayedexpansion
  8. set "a=!md:*/=!"&set "dd=!a:/=!"
  9. if "!a!" neq "!dd!" (%error%)
  10. for /f "delims=0123456789" %%i in ("!md:/=!") do (%error%)
  11. for /f "tokens=1* delims=/" %%i in ("!md!") do (endlocal&set "mm=%%i"&set "dd=%%j")
  12. setlocal enabledelayedexpansion
  13. if "!dd!"=="" (%error%)
  14. if "!mm:~2,1!" neq "" (%error%)
  15. if "!dd:~2,1!" neq "" (%error%)
  16. if "!mm:~0,1!" equ "0" if "!dd:~1,1!"=="" (%error%)
  17. if "!dd:~0,1!" equ "0" if "!mm:~1,1!"=="" (%error%)
  18. set "mm=0!mm!"&set "mm=!mm:~-2!"
  19. set "dd=0!dd!"&set "dd=!dd:~-2!"
  20. if "!dd!" gtr "00" if "!dd!" leq "!_%mm%!" (echo,Valid date&endlocal&goto :loop)
  21. %error%
复制代码
1

评分人数

TOP

本帖最后由 aloha20200628 于 2024-8-25 16:18 编辑


精简了45楼代码中的操作步骤和合法性核查逻辑,行数减至18行,8个goto减至2个...
操作步骤要点》
   双引号排查
   输入长度排查
   定界符及其错位排查
   日月值全数字排查
   日月相关变化所对应的字典变量 以及 平闰年天数增减修正
   全程严防 &!"^ 等特殊字符雷劈的对策...
再次感谢各位细心测试反馈 就算是一场把纯P贯彻到底的基本功组合复习吧...
  1. @echo off &setlocal
  2. set/a "_1=31,_2=28,_3=31,_4=30,_5=31,_6=30,_7=31,_8=31,_9=30,_10=31,_11=30,_12=31,y=%date:~,4%%%4"
  3. if %y% equ 0 set "_2=29"
  4. :[md_loop]
  5. set "$md=" &set "c=" &set/p "$md=输入日期(月值/日值):"
  6. if not defined $md endlocal&exit/b
  7. setlocal enabledelayedexpansion &set #md=!$md:"=!
  8. if "!#md!"=="!$md!" if "!$md:~5!"=="" if "!$md:~4,1!" neq "" if "!$md:~2,1!"=="/" (
  9. set "m=!$md:~0,2!"&set "d=!$md:~3!"
  10. for /f "delims=0123456789/" %%n in ("!$md!") do set "c=1"
  11. if not defined c goto[ok] )
  12. echo,非法&endlocal&goto[md_loop]
  13. :[ok]
  14. if "!m:~0,1!" equ "0" set "m=!m:~1!"
  15. set "_m=_!m!" &set "w=非法"
  16. if "!d:~0,1!" equ "0" set "d=!d:~1!"
  17. if !d! gtr 0 if !d! leq !%_m%! set "w=合法"
  18. echo,!w!&endlocal&goto[md_loop]
复制代码

TOP

返回列表