Board logo

标题: [文本处理] [讨论]短横线、单引号在批处理中if字符串比较时的规律 [打印本页]

作者: neorobin    时间: 2009-12-23 22:40     标题: [讨论]短横线、单引号在批处理中if字符串比较时的规律

将两个等长的字符串进行比较, 一个之中含有短横线, 另一个中没有, 除短横线对应一个非短横线字符外, 其余字符都一样, 并且字符串表达式中第 3 个字符同步变化, 但输出结果却会发生变化.

在第3个字符和第2个非短横线字符相同(不论大小写)之前(以及相同时), 显示 ggg 的结果, 但之后就显示 lll 的结果.
下面示例中, 第3 个字符一直到 E 都显示 ggg 的结果, 但 f 开始及之后就显示 lll 的结果.
短横线 - 在这里究竟有什么意义, 起了什么作用?  
请教~~
短横线的位置不变, 用 ' !"#$%&()*,./:;?@[\]_`{|}~+<=> 共 31 个标点符号(包括空格)逐次代换短横线(有的需转义), 发现还有 单引号 ' 也与短横线得到同样的结果, 其它字符代换的结果不随字符串表达式中 第 3 个字符的变化而变化.  ... 进一步研究中...
  1. if "e" leq "-" (echo lll) else echo ggg
  2. if "e0" leq "-0" (echo lll) else echo ggg
  3. if "e1" leq "-1" (echo lll) else echo ggg
  4. if "e2" leq "-2" (echo lll) else echo ggg
  5. if "e3" leq "-3" (echo lll) else echo ggg
  6. if "e4" leq "-4" (echo lll) else echo ggg
  7. if "e5" leq "-5" (echo lll) else echo ggg
  8. if "e6" leq "-6" (echo lll) else echo ggg
  9. if "e7" leq "-7" (echo lll) else echo ggg
  10. if "e8" leq "-8" (echo lll) else echo ggg
  11. if "e9" leq "-9" (echo lll) else echo ggg
  12. if "ea" leq "-a" (echo lll) else echo ggg
  13. if "eA" leq "-A" (echo lll) else echo ggg
  14. if "eb" leq "-b" (echo lll) else echo ggg
  15. if "eB" leq "-B" (echo lll) else echo ggg
  16. if "ec" leq "-c" (echo lll) else echo ggg
  17. if "eC" leq "-C" (echo lll) else echo ggg
  18. if "ed" leq "-d" (echo lll) else echo ggg
  19. if "eD" leq "-D" (echo lll) else echo ggg
  20. if "ee" leq "-e" (echo lll) else echo ggg
  21. if "eE" leq "-E" (echo lll) else echo ggg
  22. if "ef" leq "-f" (echo lll) else echo ggg
  23. if "eF" leq "-F" (echo lll) else echo ggg
  24. if "eg" leq "-g" (echo lll) else echo ggg
  25. if "eG" leq "-G" (echo lll) else echo ggg
  26. if "eh" leq "-h" (echo lll) else echo ggg
  27. if "eH" leq "-H" (echo lll) else echo ggg
复制代码
更多示例:
  1. if d-A lss daa echo lll
复制代码
显示 lll
  1. if d-A gtr daA (echo ggg) else echo lll
复制代码
显示 lll
  1. if d'-A gtr d9aA (echo ggg) else echo lll
复制代码
显示 ggg
  1. if d--A gtr d9aA (echo ggg) else echo lll
复制代码
显示 ggg
  1. if d'-A gtr d9'A (echo ggg) else echo lll
复制代码
显示 ggg

初步猜测:
将 ' 或 - 定义为 后邻代字号, 后邻代字号之外的字符定义为 非后邻代字号.
' 或 - 不作向后替换时, 称 ' 或 - 为相应 后邻代字号 的原义字符.
两个字符串中, 从左至右, 逐一对应位置的字符进行比较.
如果在遇到 后邻代字号 之前出现不同, 那么依据出现不同时两个字符的大小, 来决定两个字符串的大小.
如果一直达到要比较 后邻代字号, 那么 后邻代字号 的处理方式如下:
如果一个 后邻代字号 右边紧邻一个 非后邻代字号 字符, 那么此 后邻代字号 替换为那个紧邻的非后邻代字号字符;
如果一个 后邻代字号 右边紧邻仍是一个 后邻代字号, 那么先对后面的一个 后邻代字号 进行向后替换,
再对这个 后邻代字号 作一样的替换;
如果一直是连续的 后邻代字号 直到最后也没有一个 非后邻代字号, 那么, 这些连续的 后邻代字号 全部作为相应的
原义字符处理.
如果一个 后邻代字号 被替换为一个字母, 那么对它的处理不区分大小写, 即另一个相比较的字符串中对应部分是和它替换
后相同的字母时, 将忽略它们的大小写进行比较;
但这种忽略大小写的处理如果使得比较结果是两个字符串相等, 那么 后邻代字号 仍作为 原义字符 处理再来比较.

[ 本帖最后由 neorobin 于 2009-12-24 04:16 编辑 ]
作者: zqz0012005    时间: 2009-12-23 23:07

M$的东西本来就混乱。。。

开始怀疑是当成了16进制比较
把e改小一点(d→0),lll就越多;改大一点lll就越少。
还可以改变很多变数,如位置、前后字符,其他字符有没有“-”号这个特点等等。
没时间和精力继续捉摸,neorobin兄接着钻研吧。
或许有某种“不可告人”的秘密,或许根本就是乱的。
作者: neorobin    时间: 2009-12-23 23:09     标题: 回复 2楼 的帖子

是啊, 我说了 "在第3个字符和第2个非短横线字符相同(不论大小写)之前(以及相同时), " 和之后输出的结果就不同, 确实得时间琢磨啊, 呵呵呵~
作者: zqz0012005    时间: 2009-12-23 23:26

有一点没说清楚,“把e改小一点”,是指改"e0"、"e1"之类中的e,变成"a0"、"a1"、…,
改大(大于e的字母) "g0"、"g1"、…

一般不用if比较字符大小,只判断是否相等,用处不多就不必浪费太多精力在上面(以前也初步分析了一下,粗略得出符号小于数字小于字母,小写小于大写,但后来也懒得搞了)。
实在要比较还可以用vbs

PS:在findstr中也是小写小于大写,微软基本上无视ASCII码(难道M$有它自己的编码方案?)。。。
作者: neorobin    时间: 2009-12-23 23:32     标题: 回复 4楼 的帖子

哈哈, 混乱的 M$, 么事么事都藏着, 掖着, 说得个半明不白的, 让人伤脑筋
作者: 随风    时间: 2009-12-24 01:02

确实不解,看来 if 加引号后也不是单纯的逐字比较。。。
作者: batman    时间: 2009-12-24 15:40

个人猜测楼主是在测试代码时发现的这个问题吧?

楼主提出的这个问题确实令人费解,好问题!好伤脑筋!

一直对if的比较机制存在疑问,尤其是加双引号和不加双引号下的区别。。。
作者: neorobin    时间: 2009-12-24 15:49     标题: 回复 7楼 的帖子

发现此问题来源于一个实例问题: zqz 给出了一个方案, 从发现其不适应性之后接着发现了这个问题
http://bbs.bathome.net/viewthrea ... amp;page=1#pid44406
我初步提出的 后邻代字号 的猜测, 尚需严谨全面的证实
作者: zqz0012005    时间: 2009-12-24 22:13

tireless估计有不少经验。
以前对 if 这样用的比较多。
作者: Demon    时间: 2012-8-13 16:09

if在内部是使用lstrcmpW函数来比较字符串是否相等的(详见《批处理技术内幕:IF命令》

lstrcmp函数的文档中有那么一段:

The lstrcmp function uses a word sort, rather than a string sort. A word sort treats hyphens and apostrophes differently than it treats other symbols that are not alphanumeric, in order to ensure that words such as "coop" and "co-op" stay together within a sorted list. For a detailed discussion of word sorts and string sorts, see the Remarks section for the CompareString function.

连字符(hyphen)和撇号(apostrophe)会被区别对待。




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