2010-04-14 41 views
14

在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]" 

最後兩個也不會輸出字符串以上!

+0

以及FINDSTR的幫助顯示/ I開關設置不區分大小寫的模式,但我不能讓FINDSTR是大小寫敏感的,無論我用什麼樣的範圍內,太! – Axarydax 2010-04-14 08:05:07

+0

在我最初的錯誤開始後,我只能第二次(或第三次)兩次觀察。您已經爲findstr中的某個bug顯示瞭解決方法...使用完整列表變體。 – 2010-04-14 08:54:25

+0

只是一個註釋:'echo%myvar%| findstr/r'^ [AZ] * $「'實際上並不工作,如果將''^ [AZ] * $」'更改爲'abc' '「^ [AZ] * $」',它仍然會輸出'abc',如[AZ]中所示,並且錯誤級別爲0 – YOU 2010-04-14 10:12:52

回答

14

我相信這是一個可怕的設計缺陷。

我們都希望根據ASCII碼值來整理範圍。但它們不是 - 而是範圍基於排序順序,幾乎匹配SORT使用的默認順序。EDIT通過FINDSTR使用-The確切歸類序列現在可以在https://stackoverflow.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 

還有其他的字符,正則表達式排序不同於排序,但我還沒有一個確切的清單。

+0

由於社區現在重視你的答案比我的更高(並且,讓我們面對它,這是一個更好的答案,更多的解釋爲什麼會發生這種情況),我決定改變這個答案。 – paxdiablo 2012-01-14 01:23:28

2

這似乎是由正則表達式搜索中使用範圍引起的。

對於範圍中的第一個字符不會發生。對於非範圍它根本不會發生。

> 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])。對於那些被允許的人來說,更明智的做法是下載CygWinGnuWin32,並從其中一個包中使用grep

-1

以上所有人都是錯的。 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]

+0

這與我在回答中所說的沒有什麼不同:*「但是正則表達式在大寫之前顯然是小寫。」*。在我的調查過程中,我錯誤地認爲SORT命令排序在較低之前,但後來我承認這是一個錯誤 - SORT不區分與正則表達式排序順序完全無關的情況。確切的正則表達式歸類序列可在http://stackoverflow.com/a/8844873/1012053獲取 – dbenham 2015-10-11 22:26:41

3

所以,如果你想

  • 只有數字: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]*$"

相關問題