为什么 findstr 不能正确处理大小写(在某些情况下)? [英] Why does findstr not handle case properly (in some circumstances)?

查看:37
本文介绍了为什么 findstr 不能正确处理大小写(在某些情况下)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 cmd.exe 中编写一些最近的脚本时,我需要将 findstr 与正则表达式一起使用 - 客户需要的标准 cmd.exe 命令(没有 GnuWin32、Cygwin、VBS 或 Powershell).

While writing some recent scripts in cmd.exe, I had a need to use findstr with regular expressions - customer required standard cmd.exe commands (no GnuWin32 nor Cygwin nor VBS nor Powershell).

我只是想知道一个变量是否包含任何大写字符并尝试使用:

I just wanted to know if a variable contained any upper-case characters and attempted to use:

> set myvar=abc
> echo %myvar%|findstr /r "[A-Z]"
abc
> echo %errorlevel%
0

%myvar% 设置为 abc 时,实际输出字符串并将 errorlevel 设置为 0,表示找到匹配.

When %myvar% is set to abc, that actually outputs the string and sets errorlevel to 0, saying that a match was found.

但是,完整列表变体:

> echo %myvar%|findstr /r "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
> echo %errorlevel%
1

输出该行,并且正确地将 errorlevel 设置为 1.

does not output the line and it correctly sets errorlevel to 1.

另外:

> echo %myvar%|findstr /r "^[A-Z]*$"
> echo %errorlevel%
1

也按预期工作.

我显然在这里遗漏了某些东西,即使只是 findstr 以某种方式损坏了.

I'm obviously missing something here even if it's only the fact that findstr is somehow broken.

为什么第一个(范围)正则表达式在这种情况下不起作用?

Why does the first (range) regex not work in this case?

还有更奇怪的:

> echo %myvar%|findstr /r "[A-Z]"
abc
> echo %myvar%|findstr /r "[A-Z][A-Z]"
abc
> echo %myvar%|findstr /r "[A-Z][A-Z][A-Z]"
> echo %myvar%|findstr /r "[A]"

上面最后两个也不输出字符串!!

The last two above also does not output the string!!

推荐答案

我认为这主要是一个可怕的设计缺陷.

I believe this is mostly a horrible design flaw.

我们都希望范围根据 ASCII 代码值进行整理.但他们没有 - 相反,范围基于几乎与 SORT 使用的默认序列匹配的整理序列.编辑 -FINDSTR 使用的确切整理顺序现在可在 https://stackoverflow.com/a/20159191/1012053 在标题为 Regex 字符类范围 [xy] 的部分下.

We all expect the ranges to collate based on the ASCII code value. But they don't - instead the ranges are based on a collation sequence that nearly matches the default sequence used by SORT. EDIT -The exact collation sequence used by FINDSTR is now available at https://stackoverflow.com/a/20159191/1012053 under the section titled Regex character class ranges [x-y].

我准备了一个文本文件,其中包含 1 到 255 之间每个扩展 ASCII 字符的一行,不包括 10 (LF)、13 (CR) 和 26(Windows 上的 EOF).在每一行我都有一个字符,后跟一个空格,后跟该字符的十进制代码.然后我通过 SORT 运行文件并在 sortedChars.txt 文件中捕获输出.

I prepared a text file containing one line for each extended ASCII character from 1 - 255, excluding 10 (LF), 13 (CR), and 26 (EOF on Windows). On each line I have the character, followed by a space, followed by the decimal code for the character. I then ran the file through SORT and captured the output in a sortedChars.txt file.

我现在可以轻松地针对此排序文件测试任何正则表达式范围,并演示如何通过与 SORT 几乎相同的整理顺序来确定范围.

I now can easily test any regex range against this sorted file and demonstrate how the range is determined by a collation sequence that is nearly the same as SORT.

>findstr /nrc:"^[0-9]" sortedChars.txt
137:0 048
138:½ 171
139:¼ 172
140:1 049
141:2 050
142:² 253
143:3 051
144:4 052
145:5 053
146:6 054
147:7 055
148:8 056
149:9 057

结果与我们预期的不太一样,因为字符 171、172 和 253 被混合在一起.但结果是完全合理的.行号前缀对应的是SORT整理顺序,可以看到范围按照SORT顺序完全匹配.

The results are not quite what we expected in that chars 171, 172 and 253 are thrown in the mix. But the results make perfect sense. The line number prefix corresponds to the SORT collation sequence, and you can see that the range exactly matches according to the SORT sequence.

这是另一个完全遵循 SORT 序列的范围测试:

Here is another range test that exactly follows the SORT sequence:

>findstr /nrc:"^[!-=]" sortedChars.txt
34:! 033
35:" 034
36:# 035
37:$ 036
38:% 037
39:& 038
40:( 040
41:) 041
42:* 042
43:, 044
44:. 046
45:/ 047
46:: 058
47:; 059
48:? 063
49:@ 064
50:[ 091
51: 092
52:] 093
53:^ 094
54:_ 095
55:` 096
56:{ 123
57:| 124
58:} 125
59:~ 126
60:¡ 173
61:¿ 168
62:¢ 155
63:£ 156
64:¥ 157
65:₧ 158
66:+ 043
67:∙ 249
68:< 060
69:= 061

有一个带有字母字符的小异常.字符a"在A"和Z"之间排序,但它不匹配 [A-Z]."z" 在 "Z" 之后排序,但它匹配 [A-Z].[a-z] 有相应的问题."A" 在 "a" 之前排序,但它匹配 [a-z]."Z" 在 "a" 和 "z" 之间排序,但不匹配 [a-z].

There is one small anomaly with alpha characters. Character "a" sorts between "A" and "Z" yet it does not match [A-Z]. "z" sorts after "Z", yet it matches [A-Z]. There is a corresponding problem with [a-z]. "A" sorts before "a", yet it matches [a-z]. "Z" sorts between "a" and "z", yet it does not match [a-z].

以下是 [A-Z] 结果:

Here are the [A-Z] results:

>findstr /nrc:"^[A-Z]" sortedChars.txt
151:A 065
153:â 131
154:ä 132
155:à 133
156:å 134
157:Ä 142
158:Å 143
159:á 160
160:ª 166
161:æ 145
162:Æ 146
163:B 066
164:b 098
165:C 067
166:c 099
167:Ç 128
168:ç 135
169:D 068
170:d 100
171:E 069
172:e 101
173:é 130
174:ê 136
175:ë 137
176:è 138
177:É 144
178:F 070
179:f 102
180:ƒ 159
181:G 071
182:g 103
183:H 072
184:h 104
185:I 073
186:i 105
187:ï 139
188:î 140
189:ì 141
190:í 161
191:J 074
192:j 106
193:K 075
194:k 107
195:L 076
196:l 108
197:M 077
198:m 109
199:N 078
200:n 110
201:ñ 164
202:Ñ 165
203:ⁿ 252
204:O 079
205:o 111
206:ô 147
207:ö 148
208:ò 149
209:Ö 153
210:ó 162
211:º 167
212:P 080
213:p 112
214:Q 081
215:q 113
216:R 082
217:r 114
218:S 083
219:s 115
220:ß 225
221:T 084
222:t 116
223:U 085
224:u 117
225:û 150
226:ù 151
227:ú 163
228:ü 129
229:Ü 154
230:V 086
231:v 118
232:W 087
233:w 119
234:X 088
235:x 120
236:Y 089
237:y 121
238:ÿ 152
239:Z 090
240:z 122

以及 [a-z] 结果

And the [a-z] results

>findstr /nrc:"^[a-z]" sortedChars.txt
151:A 065
152:a 097
153:â 131
154:ä 132
155:à 133
156:å 134
157:Ä 142
158:Å 143
159:á 160
160:ª 166
161:æ 145
162:Æ 146
163:B 066
164:b 098
165:C 067
166:c 099
167:Ç 128
168:ç 135
169:D 068
170:d 100
171:E 069
172:e 101
173:é 130
174:ê 136
175:ë 137
176:è 138
177:É 144
178:F 070
179:f 102
180:ƒ 159
181:G 071
182:g 103
183:H 072
184:h 104
185:I 073
186:i 105
187:ï 139
188:î 140
189:ì 141
190:í 161
191:J 074
192:j 106
193:K 075
194:k 107
195:L 076
196:l 108
197:M 077
198:m 109
199:N 078
200:n 110
201:ñ 164
202:Ñ 165
203:ⁿ 252
204:O 079
205:o 111
206:ô 147
207:ö 148
208:ò 149
209:Ö 153
210:ó 162
211:º 167
212:P 080
213:p 112
214:Q 081
215:q 113
216:R 082
217:r 114
218:S 083
219:s 115
220:ß 225
221:T 084
222:t 116
223:U 085
224:u 117
225:û 150
226:ù 151
227:ú 163
228:ü 129
229:Ü 154
230:V 086
231:v 118
232:W 087
233:w 119
234:X 088
235:x 120
236:Y 089
237:y 121
238:ÿ 152
240:z 122

Sort 在小写之前对大写进行排序.(编辑 - 我刚刚阅读了 SORT 的帮助,并了解到它不区分大小写.事实上,我的 SORT 输出始终将大写在小写之前可能是输入顺序的结果.) 但正则表达式显然在大写之前对小写进行排序.以下所有范围均无法匹配任何字符.

Sort sorts upper case before lower case. (EDIT - I just read the help for SORT and learned that it does not differentiate between upper and lower case. The fact that my SORT output consistently put upper before lower is probably a result of the order of the input.) But regex apparently sorts lower case before upper case. All of the following ranges fail to match any characters.

>findstr /nrc:"^[A-a]" sortedChars.txt

>findstr /nrc:"^[B-b]" sortedChars.txt

>findstr /nrc:"^[C-c]" sortedChars.txt

>findstr /nrc:"^[D-d]" sortedChars.txt

颠倒顺序找到字符.

>findstr /nrc:"^[a-A]" sortedChars.txt
151:A 065
152:a 097

>findstr /nrc:"^[b-B]" sortedChars.txt
163:B 066
164:b 098

>findstr /nrc:"^[c-C]" sortedChars.txt
165:C 067
166:c 099

>findstr /nrc:"^[d-D]" sortedChars.txt
169:D 068
170:d 100

还有一些其他字符的正则表达式排序方式与 SORT 不同,但我没有确切的列表.

There are additional characters that regex sorts differently than SORT, but I haven't got a precise list.

这篇关于为什么 findstr 不能正确处理大小写(在某些情况下)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆