16

cmd.exe で最近のスクリプトをいくつか書いているときに、findstr正規表現を使用する必要がありました - 顧客が必要とする標準の cmd.exe コマンド (GnuWin32、Cygwin、VBS、Powershell はありません)。

変数に大文字が含まれているかどうかを知りたくて、使用しようとしました:

> 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

行を出力せ、正しくerrorlevel1 に設定されます。

加えて:

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

上記の最後の2つも文字列を出力しません!!

4

4 に答える 4

15

これは主に恐ろしい設計上の欠陥だと思います。

ASCII コード値に基づいて範囲が照合されることを期待しています。しかし、そうではありません。代わりに、範囲は、SORT で使用されるデフォルトの順序とほぼ一致する照合順序に基づいています。EDIT - FINDSTR で使用される正確な照合シーケンスは、https://stackoverflow.com/a/20159191/1012053のRegex character class ranges [xy]というタイトルのセクションで利用できるようになりました。

10 (LF)、13 (CR)、および 26 (Windows の EOF) を除く、1 から 255 までの拡張 ASCII 文字ごとに 1 行を含むテキスト ファイルを用意しました。各行に文字があり、その後にスペースが続き、その後に文字の 10 進コードが続きます。次に、ファイルを 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

アルファベット文字の小さな異常が 1 つあります。文字「a」は「A」と「Z」の間でソートされますが、[AZ] には一致しません。「z」は「Z」の後にソートされますが、[AZ] に一致します。[az] にも対応する問題があります。"A" は "a" の前に並べ替えられますが、[az] と一致します。「Z」は「a」と「z」の間でソートされますが、[az] には一致しません。

[AZ]の結果は次のとおりです。

>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

そして[az]の結果

>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

正規表現が SORT とは異なる方法でソートされる追加の文字がありますが、正確なリストはありません。

于 2012-01-07T06:15:55.910 に答える
6

だからあなたが望むなら

  • 数字のみ :FindStr /R "^[0123-9]*$"

  • 8 進数:FindStr /R "^[0123-7]*$"

  • 16 進数: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]*$"

于 2015-12-10T16:52:20.220 に答える
3

これは、正規表現検索での範囲の使用が原因のようです。

範囲内の最初の文字では発生しません。非範囲ではまったく発生しません。

> 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ページによると(循環性の見事な表示で、この質問を参照しています)、範囲[A-Z]:

... 大文字と小文字の両方の完全な英語アルファベット (「a」を除く) と、分音記号付きの英語以外のアルファベット文字が含まれます。

私の環境でこの問題を回避するために、単純に特定の正規表現 ([ABCD]ではなくなど[A-D]) を使用しました。許可されている場合のより賢明なアプローチは、CygWinまたはGnuWin32grepをダウンロードして、それらのパッケージのいずれかから使用することです。

于 2010-06-11T06:42:52.307 に答える
-1

上の人はみんな間違っています。アルファ文字の順序は次のとおりです。aAbBcCdDeE..zZ soはその範囲外であるecho a | findstr /r "[A-Z]"ため、何も返しません。a

echo abc|findstr /r "[A-Z][A-Z][A-Z]"また、最初の範囲グループは に一致bし、2 番目は に一致cし、3 番目は何も一致しないため、正規表現パターン全体で何も返されないため、何も返しません。

ラテン アルファベットの任意の文字に一致させたい場合は、 を使用します[a-Z]

于 2015-07-15T11:20:20.807 に答える