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

[文本处理] findstr无法正确判断/检测/识别/区分大小写字母,出现错误/误判

本帖最后由 pcl_test 于 2017-4-13 09:18 编辑

莫非是批处理命令findstr的BUG
是这样的
  1. @echo off & setlocal enabledelayedexpansion
  2. if exist nu.txt del nu.txt
  3. set /p a=
  4. echo !a!>nu.txt
  5. findstr "[a-z]" nu.txt >nul & if !errorlevel!==0 (echo 小写)
  6. findstr "[A-Z]" nu.txt >nul & if !errorlevel!==0 (echo 大写)
  7. del nu.txt
  8. endlocal
  9. pause
复制代码
为什么我输入 单个小写字母或大写字母时可正常运作 (如输入a 显示小写)
而输入多个如abcd时,判断就不起作用了呢?(如输入as显示 小写 大写)


还有为何if errorlevel=1可以作为判断依据而if errorlevel=0无判断效果?
高手速来!

回复 7# CrLf

在有些可以找到的源代码中可以看到如下
cbatch.c  时间戳  1997-8-27
  1. /***    eGenCmp - execute an if statement comparison - general case
  2. *
  3. *  Purpose:
  4. *      Return a nonzero value if comparison condition is met.
  5. *      Otherwise return 0.  This routine is never called unless
  6. *      command extensions are enabled.
  7. *
  8. *  int eStrCmp(struct cmdnode *n)
  9. *
  10. *  Args:
  11. *      n - the parse tree node containing the string comparison command
  12. *
  13. *  Returns:
  14. *      See above.
  15. *
  16. */
  17. int eGenCmp(n)
  18. struct cmdnode *n ;
  19. {
  20.         TCHAR *s1, *s2;
  21.         LONG n1, n2, iCompare;
  22.         n1 = _tcstol(n->cmdline, &s1, 0);
  23.         n2 = _tcstol(n->argptr, &s2, 0);
  24.         if (*s1 == NULLC && *s2 == NULLC)
  25.             iCompare = n1 - n2;
  26.         else
  27.         if (n->flag & CMDNODE_FLAG_IF_IGNCASE)
  28.             iCompare = _tcsicmp(n->cmdline, n->argptr);
  29.         else
  30.             iCompare = _tcscmp(n->cmdline, n->argptr);
  31.         switch (n->cmdarg) {
  32.         case CMDNODE_ARG_IF_EQU:
  33.             return iCompare == 0;
  34.         case CMDNODE_ARG_IF_NEQ:
  35.             return iCompare != 0;
  36.         case CMDNODE_ARG_IF_LSS:
  37.             return iCompare < 0;
  38.         case CMDNODE_ARG_IF_LEQ:
  39.             return iCompare <= 0;
  40.         case CMDNODE_ARG_IF_GTR:
  41.             return iCompare > 0;
  42.         case CMDNODE_ARG_IF_GEQ:
  43.             return iCompare >= 0;
  44.         }
  45.         return 0;
  46. }
复制代码
而对于 _tcscmp 和 _tcsicmp (前者分大小写, 后者忽略) 这两个函数
在 tchar.h 中有定义
http://research.microsoft.com/en ... include/tchar.h.htm

截取如下, 根据是否 UNICODE, 是 单字节字符集 还是 多字节字符集等判断, 出现三个实现分支.
  1. #ifdef  _UNICODE
  2.     /* ++++++++++++++++++++ UNICODE ++++++++++++++++++++ */
  3.     #define _tcscmp     wcscmp
  4.     #define _tcsicmp    _wcsicmp
  5. #else   /* _UNICODE */
  6.     /* ++++++++++++++++++++ SBCS and MBCS ++++++++++++++++++++ */
  7.     #ifdef _MBCS
  8.         /* ++++++++++++++++++++ MBCS ++++++++++++++++++++ */
  9.         #ifdef _MB_MAP_DIRECT
  10.             /* use mb functions directly - types must match */
  11.             #define _tcscmp     _mbscmp
  12.             #define _tcsicmp    _mbsicmp
  13.         #else /* _MB_MAP_DIRECT */
  14.         #endif /* _MB_MAP_DIRECT */
  15.     #else   /* !_MBCS */
  16.         /* ++++++++++++++++++++ SBCS ++++++++++++++++++++ */
  17.         #define _tcscmp     strcmp
  18.         #define _tcsicmp    _stricmp
  19.     #endif  /* _MBCS */
  20. #endif  /* _UNICODE */
复制代码
1

评分人数

TOP

回复 6# techon


    以前我问过这个问题...http://bbs.bathome.net/viewthread.php?tid=14681
    然后大伙众口一词把我K了一顿,才知道这个顺序的依据是语言与区域设置,一改区域设置这个顺序就变了,有兴趣可以去旧帖膜拜寒夜与demon二位大牛:
http://bathome.net/viewthread.php?tid=12329
http://bbs.bathome.net/viewthread.php?tid=18542
http://bbs.bathome.net/viewthread.php?tid=18493

TOP

不好意思,当时忘了考虑变量延迟问题

看来是字符排序问题,
默认排序是 a A b B c C …… x X y Y z Z

所以:
  1. @echo off
  2. echo.&echo ----未开变量延迟----
  3. echo.............................
  4. echo ab|findstr "[A-z]" && echo....[A-z]中包含a或b
  5. echo Z|findstr "[a-z]" || echo....[a-z]中不包含Z
  6. echo a|findstr "[A-Z]" || echo....[A-Z]中不包含a
  7. echo Z|findstr "[A-Z]" && echo....[A-Z]中包含Z
  8. echo.............................
  9. echo ABCDEF|findstr "a" & echo....err=%errorlevel%
  10. echo.11111.err=%errorlevel%
  11. echo.------------------
  12. echo ABCDEF|findstr "A" & echo.---ERR=%errorlevel%
  13. echo.22222.err=%errorlevel%
  14. pause
  15. setlocal enabledelayedexpansion
  16. echo.&echo //////开启变量延迟\\\\\\
  17. echo.==========================
  18. echo ABCDEF|findstr "a" & echo....err=!errorlevel!
  19. echo.11111.err=!errorlevel!
  20. echo.------------------
  21. echo ABCDEF|findstr "A" & echo.---ERR=!errorlevel!
  22. echo.22222.err=!errorlevel!
  23. pause&goto :eof
复制代码
解释执行的脚本语言与编译语言还是有很大差别的。。。

TOP

回复 4# techon


把你的测试结果发出来看看?

c:\>echo HAT | findstr "H"
HAT

c:\>echo %errorlevel%
0

c:\>echo HAT | findstr "h"

c:\>echo %errorlevel%
1

c:\>findstr "H" a.txt
HAT

c:\>echo %errorlevel%
0

c:\>findstr "h" a.txt

c:\>echo %errorlevel%
1

TOP

本帖最后由 techon 于 2014-9-13 17:32 编辑
findstr 在文件中查找字符,不管是否找到字符,都不会将 %errorlevel% 置为 1

%errorlevel% 只是在命令出错时被置位, 如找不到 “nu.txt” 的情况下


这个说法不对,忘记变量延迟的问题了
  1. echo ABCDEF|findstr "a" & echo....err=%errorlevel%
  2. echo....ERR=%errorlevel%
复制代码
解释执行的脚本语言与编译语言还是有很大差别的。。。

TOP

  1. @echo off & setlocal enabledelayedexpansion
  2. if exist nu.txt del nu.txt
  3. set /p a=
  4. echo !a!>nu.txt
  5. findstr "[a-z]" nu.txt >nul && echo 小写
  6. findstr "[A-Z]" nu.txt >nul && echo 大写
  7. del nu.txt
  8. endlocal
  9. pause
复制代码
为毛不这样写

TOP

我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

返回列表