为什么findstr不能正确处理案件(在某些情况下)?
在cmd.exe中编写一些最新的脚本时,我需要使用findstr
以及正则表达式 - 客户需要的标准cmd.exe命令(无GnuWin32,Cygwin,VBS或Powershell)。为什么findstr不能正确处理案件(在某些情况下)?
我只是想知道,如果一个变量包含任何大写字符,并尝试使用:
> set myvar=abc
> echo %myvar%|findstr /r "[A-Z]"
abc
> echo %errorlevel%
0
当%myvar%
设置为abc
,实际输出字符串,并设置errorlevel
为0,说一场比赛被发现。
然而,全名单变种:
> echo %myvar%|findstr /r "[ABCDEFGHIJKLMNOPQRSTUVWXYZ]"
> echo %errorlevel%
1
不不输出线并正确设置errorlevel
为1
另外:
> echo %myvar%|findstr /r "^[A-Z]*$"
> echo %errorlevel%
1
也适用如预期。
我很明显缺少东西这里即使它只是findstr
在某种程度上被打破的事实。
为什么第一个(范围)正则表达式在这种情况下不起作用?
并且还更古怪:
> 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]"
最后两个也不会输出字符串以上!
我相信这是一个可怕的设计缺陷。
我们都希望根据ASCII码值来整理范围。但它们不是 - 而是范围基于排序顺序,几乎匹配SORT使用的默认顺序。EDIT通过FINDSTR使用-The确切归类序列现在可以在https://*.com/a/20159191/1012053下标题的Regex字符类范围[X-Y]部分。
我准备了一个文本文件,其中包含1到255的每个扩展ASCII字符的一行,不包括10(LF),13(CR)和26(EOF在Windows上)。 在每行上我都有字符,后跟一个空格,后面跟着字符的十进制代码。然后我通过SORT运行该文件,并在sortedChars.txt文件中捕获输出。
我现在可以很容易地测试任何正则表达式范围对这个排序文件,并演示范围是如何通过与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序列看到范围完全匹配。
下面是恰好跟随SORT序列另一个范围测试:
>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]不匹配。
下面是[A-Z]结果:
>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]导致
>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输出始终低于上一个可能是输入顺序的结果。)但是,正则表达式在大写之前显然是小写。以下所有范围都无法匹配任何字符。
>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
还有其他的字符,正则表达式排序不同于排序,但我还没有一个确切的清单。
由于社区现在重视你的答案比我的更高(并且,让我们面对它,这是一个更好的答案,更多的解释为什么会发生这种情况),我决定改变这个答案。 – paxdiablo 2012-01-14 01:23:28
这似乎是由正则表达式搜索中使用范围引起的。
对于范围中的第一个字符不会发生。对于非范围它根本不会发生。
> echo a | findstr /r "[A-C]"
> echo b | findstr /r "[A-C]"
b
> echo c | findstr /r "[A-C]"
c
> echo d | findstr /r "[A-C]"
> echo b | findstr /r "[B-C]"
> echo c | findstr /r "[B-C]"
c
> echo a | findstr /r "[ABC]"
> echo b | findstr /r "[ABC]"
> echo c | findstr /r "[ABC]"
> echo d | findstr /r "[ABC]"
> echo b | findstr /r "[BC]"
> echo c | findstr /r "[BC]"
> echo A | findstr /r "[A-C]"
A
> echo B | findstr /r "[A-C]"
B
> echo C | findstr /r "[A-C]"
C
> echo D | findstr /r "[A-C]"
按照SS64 CMD FINDSTR
page(在圆的一个惊人的显示,参考这个问题),该范围[A-Z]
:
...包括完整的英文字母,大写和小写(除了“a”),以及非英语字母与变音符号。
为了解决在我的环境问题,我只是用特定的正则表达式(如[ABCD]
而非[A-D]
)。对于那些被允许的人来说,更明智的做法是下载CygWin或GnuWin32,并从其中一个包中使用grep
。
以上所有人都是错的。 alpha字符顺序是follwoing:aAbBcCdDeE..zZ
所以echo a | findstr /r "[A-Z]"
返回什么都没有,因为a
超出该范围。
echo abc|findstr /r "[A-Z][A-Z][A-Z]"
也不返回任何内容,因为第一范围组匹配b
,第二个匹配c
,第三个匹配任何内容,因此整个正则表达式模式找不到任何内容。
如果您想匹配拉丁字母的任何字符 - 请使用[a-Z]
。
这与我在回答中所说的没有什么不同:*“但是正则表达式在大写之前显然是小写。”*。在我的调查过程中,我错误地认为SORT命令排序在较低之前,但后来我承认这是一个错误 - SORT不区分与正则表达式排序顺序完全无关的情况。确切的正则表达式归类序列可在http://*.com/a/8844873/1012053获取 – dbenham 2015-10-11 22:26:41
所以,如果你想
只有数字:
FindStr /R "^[0123-9]*$"
八:
FindStr /R "^[0123-7]*$"
十六进制:
FindStr /R "^[0123-9aAb-Cd-EfF]*$"
阿尔法没有重音:
FindStr /R "^[aAb-Cd-EfFg-Ij-NoOp-St-Uv-YzZ]*$"
字母:
FindStr /R "^[0123-9aAb-Cd-EfFg-Ij-NoOp-St-Uv-YzZ]*$"
以及FINDSTR的帮助显示/ I开关设置不区分大小写的模式,但我不能让FINDSTR是大小写敏感的,无论我用什么样的范围内,太! – Axarydax 2010-04-14 08:05:07
在我最初的错误开始后,我只能第二次(或第三次)两次观察。您已经为findstr中的某个bug显示了解决方法...使用完整列表变体。 – 2010-04-14 08:54:25
只是一个注释:'echo%myvar%| findstr/r'^ [AZ] * $“'实际上并不工作,如果将''^ [AZ] * $”'更改为'abc' '“^ [AZ] * $”',它仍然会输出'abc',如[AZ]中所示,并且错误级别为0 – YOU 2010-04-14 10:12:52