Board logo

标题: [文本处理] 批处理怎样快速简洁判断一个字母是大写还是小写? [打印本页]

作者: plp626    时间: 2011-5-12 21:20     标题: 批处理怎样快速简洁判断一个字母是大写还是小写?

如题,这个问题的思考源于 这个帖子
16进制数据最小体积存储
在此求助下。。谢谢。
作者: batman    时间: 2011-5-12 21:48

这个还是容易吧:
  1. @echo off&setlocal enabledelayedexpansion
  2. for %%a in (a-A b-B c-C d-D e-E f-F g-G h-H i-I j-J k-K l-L m-M n-N o-O p-P q-Q r-R s-S t-T u-U v-V w-W x-X y-Y z-Z) do (
  3.      for /f "tokens=1* delims=-" %%b in ("%%a") do set "%%b=%%c"
  4. )
  5. set /p str=请输入:
  6. if "!%str%!" equ "%str%" (
  7.    echo 大写
  8.   ) else (
  9.    echo 小写
  10. )
  11. pause>nul
复制代码

作者: plp626    时间: 2011-5-12 21:51

查表法,恩,是很快。

===============
有代码再短的么? 比如变量的~那种扩展可以把它判断出来的么?
作者: batman    时间: 2011-5-12 21:54

  1. @echo off
  2. set "ans=小写"
  3. set /p str=请输入:
  4. if "%str%" geq  "A" if "%str%" leq "Z" set "ans=大写"
  5. echo %ans%
  6. pause>nul
复制代码

作者: plp626    时间: 2011-5-12 22:01

好的,此贴已结

如果有哪位能找到比四楼更简洁的方法,告诉我好让我佩服一下。。。
作者: batman    时间: 2011-5-12 22:01

本帖最后由 batman 于 2011-5-12 22:12 编辑
  1. @echo off
  2. set /p str=请输入:
  3. subst %str%: %cd%
  4. cd /d %str%:
  5. for %%a in (%str%) do (
  6.      if "%%~da" equ "%%a:" (
  7.         echo 大写
  8.        ) else (
  9.        echo 小写
  10.      )
  11.      subst /d %%a:
  12. )
  13. pause>nul
复制代码

作者: plp626    时间: 2011-5-12 22:06

6# batman


你测试了? 我这里不行啊,

%~da是扩展到默认分区,是个固定值吧。

x 试试,
作者: plp626    时间: 2011-5-12 22:08

不是x,

A试试。。。
作者: batman    时间: 2011-5-12 22:12

这下6楼行了
作者: plp626    时间: 2011-5-12 22:14

本帖最后由 plp626 于 2011-5-12 22:15 编辑
  1. for /f "delims=abcdefghijklmnopqrstuvwxyz" %%a in (":%1")do if %%a=: (echo 小写)else echo 大写
复制代码
我刚想到的方法,但比起四楼的还是少了些简洁。

======================


继续等待 佩服的人 出现。。。。
作者: plp626    时间: 2011-5-12 22:17

9# batman


恩,可我还是喜欢你四楼的代码,,,

subst 可是外部命令啊,速度,,速度。。。。?
作者: batman    时间: 2011-5-12 22:18

11# plp626
只是多提供一种思路罢了。。。
作者: batman    时间: 2011-5-12 22:26

四楼还可以短一点点:
  1. @echo off
  2. set "ans=大写"
  3. set /p str=请输入:
  4. if "%str%" geq "a" set "ans=小写"
  5. echo %ans%
  6. pause>nul
复制代码

作者: plp626    时间: 2011-5-12 22:33

13# batman

精简代码要这样,看,多简洁,还是你的思路。
  1. if %1 geq a (echo 小写)else 大写
复制代码

作者: vsbat    时间: 2011-5-12 23:17

对于4L 代码。。有问题吧
比如输入 b
输入 c
。。。

对于13L同样。。。输入 Q 显示小写 。。
作者: batman    时间: 2011-5-12 23:20

实验证明只有2 6 10三种方法是正确的,这个if真的是让人头痛。。。
作者: plp626    时间: 2011-5-12 23:24

15# vsbat

这个还真没注意,注意力集中在思路上了,也没做测试。

但可以挽救。。
作者: yjstone    时间: 2011-5-13 00:58

实验证明只有2 6 10三种方法是正确的,这个if真的是让人头痛。。。
batman 发表于 2011-5-12 23:20

6楼的恐怕也不行吧,即使行实用程度也有限,不能输入与系统已有盘符相同的字母的。
作者: batman    时间: 2011-5-13 01:04

本帖最后由 batman 于 2011-5-13 01:05 编辑

18# yjstone
加个>nul 2>nul就可以了
  1. @echo off
  2. set /p str=请输入:
  3. subst %str%: %cd%>nul 2>nul
  4. cd /d %str%:
  5. for %%a in (%str%) do (
  6.      if "%%~da" equ "%%a:" (
  7.         echo 大写
  8.        ) else (
  9.        echo 小写
  10.      )
  11.      subst /d %%a:>nul 2>nul
  12. )
  13. pause>nul
复制代码

作者: yjstone    时间: 2011-5-13 01:24

我也写一个吧,利用if不加/i参数是区分大小写的。
  1. @echo off
  2. set /p letter=请输入一个字母:
  3. for %%i 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 "%letter%"=="%%i" echo 小写&pause>nul&exit
  4. echo 大写
  5. pause>nul
复制代码

作者: yjstone    时间: 2011-5-13 02:00

再来一个,利用for变量是区分大小写的特点。
  1. @echo off&set str="1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1:1"
  2. set /p letter=请输入一个字母:
  3. for /f "tokens=1-26 delims=:" %%a in (%str%) do if "%%%letter%"=="1" echo 小写&pause>nul&pause
  4. echo 大写
  5. pause>nul
复制代码

作者: hanyeguxing    时间: 2011-5-13 03:12

本帖最后由 hanyeguxing 于 2011-5-13 15:41 编辑

既然已经限定一个字母,那么:
  1. for %%a 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 set #%%a=%%a
  2. if "A"=="%#A%" (echo;小写) else echo;大写
复制代码
%#A%变量名忽略大小写,变量值则区分;而 if  默认比较是区分大小写的
作者: neorobin    时间: 2011-5-13 03:27

本帖最后由 neorobin 于 2011-5-13 03:42 编辑

6楼的代码没必要用 subst
  1. @echo off
  2. set /p c=input:
  3. for %%i in (%c%:) do if %c%:==%%~di (echo UPPER) else echo lower
复制代码

作者: neorobin    时间: 2011-5-13 03:53

23# neorobin
if 比较时, 字母表次序是这样的:
  1. 43:{a}
  2. 44:{A}
  3. 45:{b}
  4. 46:{B}
  5. 47:{c}
  6. 48:{C}
  7. 49:{d}
  8. 50:{D}
  9. 51:{e}
  10. 52:{E}
  11. 53:{f}
  12. 54:{F}
  13. 55:{g}
  14. 56:{G}
  15. 57:{h}
  16. 58:{H}
  17. 59:{i}
  18. 60:{I}
  19. 61:{j}
  20. 62:{J}
  21. 63:{k}
  22. 64:{K}
  23. 65:{l}
  24. 66:{L}
  25. 67:{m}
  26. 68:{M}
  27. 69:{n}
  28. 70:{N}
  29. 71:{o}
  30. 72:{O}
  31. 73:{p}
  32. 74:{P}
  33. 75:{q}
  34. 76:{Q}
  35. 77:{r}
  36. 78:{R}
  37. 79:{s}
  38. 80:{S}
  39. 81:{t}
  40. 82:{T}
  41. 83:{u}
  42. 84:{U}
  43. 85:{v}
  44. 86:{V}
  45. 87:{w}
  46. 88:{W}
  47. 89:{x}
  48. 90:{X}
  49. 91:{y}
  50. 92:{Y}
  51. 93:{z}
  52. 94:{Z}
复制代码
所以 4 楼, 13 楼, 14 楼不行
作者: plp626    时间: 2011-5-13 10:55

24# neorobin


字符顺序确实如此,if 判断非ascii顺序,自有它的一套规则。

看来四楼那种思路 很难挽救了。。
作者: hanyeguxing    时间: 2011-5-13 14:41

本帖最后由 hanyeguxing 于 2011-5-13 18:17 编辑

25# plp626


if [not] string1 compareop string2 command [else expression] 这里 if 执行的是值(含义)比较,值相等时则按扩展顺序(默认小写字母在前、英文在前)决定大小;数字时则直接相等;含义的扩展,则由代码页决定。
所以不同代码页下比较的结果很可能是不同的,而我们通常所说的比较结果实际是英文437内核简体中文936扩展下的比较结果,例如:
  1. if ⒉ lss 3 (echo 1) else echo;2
  2. pause&chcp 850 >nul
  3. if ⒉ lss 3 (echo 3) else echo;4
  4. pause
复制代码

作者: CrLf    时间: 2011-5-13 15:08

6楼的代码没必要用 subst@echo off
set /p c=input:
for %%i in (%c% do if %c%:==%%~di (echo UPPER) else echo lower
neorobin 发表于 2011-5-13 03:27

曾以为,自己差不多勉强有技术组水平了,但是老兄用代码对我说:你丫夜郎自大...
再次膜拜一下neorobin
作者: plp626    时间: 2011-5-13 16:20

26# hanyeguxing
  1. ⒉ 不是2.
复制代码
没错。

不过,我差点被你忽悠了。

你那个⒉ 是双字节字符,确切的内在机制或者规则还望大家研究下。
作者: hanyeguxing    时间: 2011-5-13 16:31

本帖最后由 hanyeguxing 于 2011-5-13 16:39 编辑

28# plp626


1,在 936代码页 下 ⒉ 是小于 3 的,而在 437代码页下是大于 3 的
2,为什么总记挂着他是单字节还是双字节呢? cmd 中所有字符都是按宽字符处理的
在 cmd 中,以 fgets 函数转换字符串为宽字符;然后:
wcscmp 比较两个宽字符串(宽字符)
wcsncmp 类似于wcscmp(), 还要指定比较字符字符串的数目(宽字符)
iswspace 测试字符是否是空白符号(宽字符)
iswdigit 测试字符是否为数字(宽字符)
iswxdigit 测试字符是否是十六进制的数字(宽字符)
iswalpha 测试字符是否是字母(宽字符)
towlower 把字符转换为小写(宽字符)
towupper 把字符转换为大写(宽字符)
wcslen 获得宽字符串的数目(宽字符)
wcstol 把宽字符的初始部分转换为长整数(宽字符)
wcstoul 把宽字符的初始部分转换为无符号长整数(宽字符)
wcsstr 在一字符串中查找另一字符串第一次出现的位置(宽字符)
wcscat 把一个字符串接到另一个字符串的尾部(宽字符)
wcsrchr 从尾部开始查找子字符串出现的第一个位置(宽字符)
swprintf 根据vararg参量表格式化成字符串(宽字符)
wcscpy 拷贝字符串(宽字符)
wcsncpy 类似于wcscpy(), 同时指定拷贝的数目(宽字符)
wcschr 查找子字符串的第一个位置(宽字符)
wcsspn 返回包含第二个字符串的初始数目(宽字符)
还有很多。。。
作者: plp626    时间: 2011-5-13 16:40

29# hanyeguxing

很专业似的。我也没考证过。

你能得到这些,那给个宽字符顺序表?

65535个字符

不知如何比较呢? 内在机制到底是怎样的?

比如任给两个字符,汉字,怎么通过winhex比较他俩在cmd下if 判断的大小顺序,chcp437代码页下又是怎么样的?
作者: CrLf    时间: 2011-5-13 17:45

29# hanyeguxing


复杂,期待深入的解答
作者: techon    时间: 2011-5-15 10:44

本帖最后由 techon 于 2011-5-15 10:48 编辑
  1. "" ascii=1
  2. "" ascii=2
  3. "" ascii=3
  4. "" ascii=4
  5. "" ascii=5
  6. "" ascii=6
  7. "" ascii=7
  8. "" ascii=8
  9. "" ascii=14
  10. "" ascii=15
  11. "" ascii=16
  12. "" ascii=17
  13. "" ascii=18
  14. "" ascii=19
  15. "" ascii=20
  16. "" ascii=21
  17. "" ascii=22
  18. "" ascii=23
  19. "" ascii=24
  20. "" ascii=25
  21. "" ascii=27
  22. "" ascii=28
  23. "" ascii=29
  24. "" ascii=30
  25. "" ascii=31
  26. "�" ascii=127
  27. "'" ascii=39
  28. "-" ascii=45
  29. " " ascii=32
  30. "{TAB}" ascii=9
  31. "" ascii=11
  32. " " ascii=12
  33. "!" ascii=33
  34. """ ascii=34
  35. "#" ascii=35
  36. "$" ascii=36
  37. "%" ascii=37
  38. "&" ascii=38
  39. "(" ascii=40
  40. ")" ascii=41
  41. "*" ascii=42
  42. "," ascii=44
  43. "." ascii=46
  44. "/" ascii=47
  45. ":" ascii=58
  46. ";" ascii=59
  47. "?" ascii=63
  48. "@" ascii=64
  49. "[" ascii=91
  50. "\" ascii=92
  51. "]" ascii=93
  52. "^" ascii=94
  53. "_" ascii=95
  54. "`" ascii=96
  55. "{" ascii=123
  56. "|" ascii=124
  57. "}" ascii=125
  58. "~" ascii=126
  59. "+" ascii=43
  60. "<" ascii=60
  61. "=" ascii=61
  62. ">" ascii=62
  63. "€" ascii=128
  64. "0" ascii=48
  65. "1" ascii=49
  66. "2" ascii=50
  67. "3" ascii=51
  68. "4" ascii=52
  69. "5" ascii=53
  70. "6" ascii=54
  71. "7" ascii=55
  72. "8" ascii=56
  73. "9" ascii=57
  74. "a" ascii=97
  75. "A" ascii=65
  76. "b" ascii=98
  77. "B" ascii=66
  78. "c" ascii=99
  79. "C" ascii=67
  80. "d" ascii=100
  81. "D" ascii=68
  82. "e" ascii=101
  83. "E" ascii=69
  84. "f" ascii=102
  85. "F" ascii=70
  86. "g" ascii=103
  87. "G" ascii=71
  88. "h" ascii=104
  89. "H" ascii=72
  90. "i" ascii=105
  91. "I" ascii=73
  92. "j" ascii=106
  93. "J" ascii=74
  94. "k" ascii=107
  95. "K" ascii=75
  96. "l" ascii=108
  97. "L" ascii=76
  98. "m" ascii=109
  99. "M" ascii=77
  100. "n" ascii=110
  101. "N" ascii=78
  102. "o" ascii=111
  103. "O" ascii=79
  104. "p" ascii=112
  105. "P" ascii=80
  106. "q" ascii=113
  107. "Q" ascii=81
  108. "r" ascii=114
  109. "R" ascii=82
  110. "s" ascii=115
  111. "S" ascii=83
  112. "t" ascii=116
  113. "T" ascii=84
  114. "u" ascii=117
  115. "U" ascii=85
  116. "v" ascii=118
  117. "V" ascii=86
  118. "w" ascii=119
  119. "W" ascii=87
  120. "x" ascii=120
  121. "X" ascii=88
  122. "y" ascii=121
  123. "Y" ascii=89
  124. "z" ascii=122
  125. "Z" ascii=90
复制代码
用if 比较了一下
其中
"{SUB}"        ascii=26
"{CR}"        ascii=13
"{LF}"        ascii=10

因为没法用变量处理 所以不在比较范围内
作者: CrLf    时间: 2011-5-15 10:49

28# plp626


1,在 936代码页 下 ⒉ 是小于 3 的,而在 437代码页下是大于 3 的
2,为什么总记挂着他是单字节还是双字节呢? cmd 中所有字符都是按宽字符处理的
在 cmd 中,以 fgets 函数转换字符串为宽字符 ...
hanyeguxing 发表于 2011-5-13 16:31

寒夜孤星怎么什么都知道...
作者: neorobin    时间: 2011-5-15 10:55

32# techon
与我以前做过的 ASCII (码值从 32 到 126) 测试结果不相同, 可否贴出完全测试代码(或发出文件附件避免特殊字符损失)
作者: techon    时间: 2011-5-15 12:24

本帖最后由 techon 于 2011-5-15 12:47 编辑
32# techon
与我以前做过的 ASCII (码值从 32 到 126) 测试结果不相同, 可否贴出完全测试代码(或发出文件附件避免特殊字符损失)
neorobin 发表于 2011-5-15 10:55


这里还有个问题 就是if 判断的时候 使用
  1. if “字符变量” gtr “字符变量”
  2. if 字符变量 gtr 字符变量
复制代码
带引号和不带引号的排序是不一样, 这个好像跟if 对字符处理的位数有关,究竟是按8位字符处理 还是按16位字符处理还有待研究
作者: CrLf    时间: 2011-5-15 13:01

35# techon


不带引号是数值比较,而带引号则是字符串比较
作者: powerbat    时间: 2011-5-15 13:07

32# techon
除了ascii=00外,其余255个ascii字符都可以用变量表示。
PS:你把ASCII表贴出来有啥意义啊,大家都知道滴。第一眼还以为是你的研究结果,晕。。。

35# techon
if “字符变量” gtr “字符变量”,是纯字符比较
if 字符变量 gtr 字符变量,视变量值的不同,系统会选择采用数字比较或字符比较。
作者: plp626    时间: 2011-5-15 18:15

32# techon
除了ascii=00外,其余255个ascii字符都可以用变量表示。
PS:你把ASCII表贴出来有啥意义啊,大家都知道滴。第一眼还以为是你的研究结果,晕。。。

35# techon
if “字符变量” gtr “字符变量”, ...
powerbat 发表于 2011-5-15 13:07



看 techon 是新注册会员,你这样会打击新人积极性的。
作者: abcdshenji    时间: 2011-5-15 21:48

本帖最后由 abcdshenji 于 2011-5-15 21:50 编辑

37# powerbat


我忍不住得说你两句。。你都知道ascii码是吧。。好考考你。。ascii=15到ascii=35之间都有哪些字符?请迅速回答。。我只想说的是,不要随便打击新人。。还有很多新人(比如我)不知道ASCII表的。。如果你回答不出来。。不好意思请你谦虚点可以吗。。
作者: qzwqzw    时间: 2011-5-15 22:10

本帖最后由 qzwqzw 于 2011-5-15 22:22 编辑

30# plp626
基本上可以确定是wcscmp和wcsncmp
还有忽略大小写的_wcsicmp
是按照字典序(lexicographic comparison)进行比较
这个字典序跟代码页相关
主要是在locale中的LC_COLLATE中指定
中文环境下cmd.exe的LC_COLLATE值为
Chinese_People's Republic of China.936
进一步的信息还未获取到
作者: powerbat    时间: 2011-5-15 23:02

39# abcdshenji
完全没有打击的意思,我只是想抱怨一下“第一眼还以为是你的研究结果”,仔细看才发现是ASCII表——我不是搞编程的,对ASCII也完全不熟(不然不必“仔细”),不查表也不知道ascii=15到ascii=35之间都有哪些字符,只是有这个概念,见到了它知道它是个啥,不至于两眼一抹黑。——其实我想表达的意思是,作者应该把“ASCII表”这几个字交待一下,免得误解。

不要被37楼“会打击新人积极性的”给误导了,呵呵,plp626是牛人,不能和他比。
作者: Batcher    时间: 2011-5-15 23:13

闻道有先后,术业有专攻,如是而已。
切磋,切磋,如切如磋。
淡定了大家。
作者: caruko    时间: 2011-5-17 17:18

本帖最后由 caruko 于 2011-5-17 17:27 编辑

echo %1|findstr "[ABCDEFGHIJKLMNOPQRSTWUYXYZ]">nul &&echo 大写||echo 小写

发现 [A-Z] 的写法有问题
作者: CrLf    时间: 2011-5-17 17:47

echo %1|findstr "[ABCDEFGHIJKLMNOPQRSTWUYXYZ]">nul &&echo 大写||echo 小写

发现 [A-Z] 的写法有问题
caruko 发表于 2011-5-17 17:18

怪事,我试了下还真是,为什么会出现这么奇怪的现象...
作者: powerbat    时间: 2011-5-17 20:16

什么叫“怪事”啊?楼上不是经常关注这些帖子吗?24楼就有答案:
if 比较时, 字母表次序是这样的:
43:{a}
44:{A}
45:{b}
46:{B}
...
其实不只是if,findstr也如此。
此帖更全面:[分享]ASCII码单字符 批处理IF命令比较顺序
此帖有原理说明:Windows 代码页与字符顺序
第一类如 if 、sort 等,按以上顺序排列字符;其他 32 位程序绝大多数也是如此,例如资源管理器、外壳程序等等。
作者: CrLf    时间: 2011-5-17 20:26

本帖最后由 zm900612 于 2011-5-17 20:28 编辑
什么叫“怪事”啊?楼上不是经常关注这些帖子吗?24楼就有答案:
if 比较时, 字母表次序是这样的:
43:{a}
44:{A}
45:{b}
46:{B}
...
其实不只是if,findstr也如此。
此帖更全面:[分享]ASCII码单字符 批处理 ...
powerbat 发表于 2011-5-17 20:16

很早就知道if中字符的大小排序自有其规律,但是findstr...我以前一直以为[A-Z]就是纯大写,既然用了正则,为什么还搞这么大一个漏洞,害死人了
不过既然是按ansi码排序,那以后可以这么用了:
  1. echo>a.txt ;
  2. findstr "[:-=]" a.txt
复制代码





欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2