При записи некоторых недавних сценариев в 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
не производит строку, и она правильно устанавливает errorlevel
к 1.
Кроме того:
> echo %myvar%|findstr /r "^[A-Z]*$"
> echo %errorlevel%
1
также работы как ожидалось.
Я, очевидно, пропускаю что-то здесь, даже если это - только факт это findstr
так или иначе повреждается.
Почему первое (располагается), regex не работают в этом случае?
И все же больше странности:
> 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]"
Последние два выше также не производят строку!!
Похоже, это вызвано использованием диапазонов в регулярных выражениях поиска.
Это не происходит для первого символа в диапазоне. Для недиапазонов это вообще не происходит.
> 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 или GnuWin32 и использовать grep
из одного из этих пакетов.