Как написать шаблон поиска, чтобы включить пробел в findstr?
Я хочу искать все файлы в определенном каталоге для появления таких операторов, как
Load frmXYZ
Я нахожусь в Windows 7, используя команду findstr
. Я пробовал:
findstr /n Load.*frm *.*
Но это дает мне нежелательные результаты, такие как:
If ABCFormLoaded Then Unload frmPQR
Итак, я попытался установить пробел между Load
и frm
и дал команду следующим образом:
findstr /n Load frm *.*
Но это просто искало все вхождения слова Load
или все вхождения слова frm
. Как мне решить эту проблему?
Ответы
Ответ 1
Если вы используете пробелы, вам нужна опция /C:
, чтобы передать литеральную строку (строки) в параметр regex /R
.
Когда он попадает в регулярное выражение, он рассматривается как регулярное выражение.
Тем не менее, это типичный мусор MS.
Используйте две строки поиска регулярных выражений
Суть в том, что вы должны использовать 2 строки для обработки случаев, где
Load frm
находится в начале так:
-
Load frm apples bananas carrots
ИЛИ в середине так:
-
some other text Load frm and more
.
Версия без классов символов
Ниже используется XP sp3, окна 7 могут быть разными, оба являются корзинами!
findstr /N /R /C:" *Load *frm" /C:"^Load *frm" test.txt
7:Load frm is ok
8: Load frm is ok
Обратите внимание на Colon
ПРИМЕЧАНИЕ. Двоеточие в /C:
является ОБЯЗАТЕЛЬНЫМ, чтобы это работало.
Если вы обойдете двоеточие, то обработка ошибок findstr
предназначена только для того, чтобы лечить /C
как недопустимую опцию, игнорировать эту недопустимую опцию и идти в любом случае. Превращение в неожиданный и нежелательный вывод.
Эквивалентная версия с использованием классов символов
findstr /N /R /C:"[ ][ ]*Load[ ][ ]*frm" /C:"^Load[ ][ ]*frm" test.txt
Разбиение классов символов
// The first regex search string breaks down like this:
[ ] // require 1 space
[ ]* // optional many spaces
Load // literal 'Load'
[ ] // require 1 space
[ ]* // optional many spaces
frm // literal 'frm'
// The second regex search string breaks down like this:
^ // beginning of line
Load // literal 'Load'
[ ] // require 1 space
[ ]* // optional many spaces
frm // literal 'frm'
Реальное регулярное выражение может быть \bLoad\s+frm
Ответ 2
Используйте параметр /c
:
findstr /n /c:"Load frm" *.*
Из справки (findstr /?
):
/C:string Uses specified string as a literal search string.
Ответ 3
Этот фрагмент кода допускает только буквы, цифры, подчеркивание и пробел в ключевом слове:
set /p keyword="Enter keyword: " || Set keyword=
set keyword_replaced=%keyword: =_%
echo %keyword_replaced%| findstr /r "[^0-9a-zA-Z_]" > nul
if errorlevel 1 goto noexit
echo special characters in keyword not allowed (except space and _), TERMINATING
timeout 4
exit /b 0
:noexit
Ответ 4
Использовать регулярное выражение разделителя слов
Я использовал специальный символ \<
"начало слова" regex.
Я попробовал это на Win98-версии findstr. Но в соответствии с Microsoft этот специальный символ \<
был в findstr.exe
с момента WinXP.
Полная (и болезненная) разбивка многих параметров, которые НЕ работают ниже.
В самом низу: что на самом деле сработало.
Сам образец файла
C:\>type lines.txt
Load frmXYZ // This line should match.
If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
pears Load frm grapes pineapples // This line should match.
// This blank line should NOT match.
LOAD FRMXYZ // This line should match.
IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
PEARS LOAD FRM GRAPES PINEAPPLES // This line should match.
// This blank line should NOT match.
load frmxyz // This line should match.
if abcformloaded then unload frmpqr // This line should NOT match.
pears load frm grapes pineapples // This line should match.
Неправильно. С регулярным пространством выполнения рассматривается как разделитель.
C:\>type lines.txt | findstr /N "Load frm"
1:Load frmXYZ // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples // This line should match.
9:load frmxyz // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples // This line should match.
Неверно: с дополнительным пространством Regex STILL рассматривается как разделитель.
C:\>type lines.txt | findstr /N /R "Load frm"
1:Load frmXYZ // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples // This line should match.
9:load frmxyz // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples // This line should match.
Правильнее, но все еще неправильно. С опцией /C мы теперь получаем сохраненные пробелы, но не находим другие случаи символов.
C:\>type lines.txt | findstr /N /R /C:"Load frm"
1:Load frmXYZ // This line should match.
3:pears Load frm grapes pineapples // This line should match.
Неправильно. /I для "Ignore Case" не помогает. Мы получаем совпадения из слов, которые нам не нужны.
C:\>type lines.txt | findstr /N /R /I /C:"Load frm"
1:Load frmXYZ // This line should match.
2:If ABCFormLoaded Then Unload frmPQR // This line should NOT match.
3:pears Load frm grapes pineapples // This line should match.
5:LOAD FRMXYZ // This line should match.
6:IF ABCFORMLOADED THEN UNLOAD FRMPQR // This line should NOT match.
7:PEARS LOAD FRM GRAPES PINEAPPLES // This line should match.
9:load frmxyz // This line should match.
10:if abcformloaded then unload frmpqr // This line should NOT match.
11:pears load frm grapes pineapples // This line should match.
Right. Используйте специальный символ "Начало слова" регулярного выражения. Соответствует началу строки или пробелу.
Любой чувствительный к регистру:
C:\>type lines.txt | findstr /N /R /C:"\<Load frm"
1:Load frmXYZ // This line should match.
3:pears Load frm grapes pineapples // This line should match.
или игнорируя регистр
C:\>type lines.txt | findstr /N /R /I /C:"\<Load frm"
1:Load frmXYZ // This line should match.
3:pears Load frm grapes pineapples // This line should match.
5:LOAD FRMXYZ // This line should match.
7:PEARS LOAD FRM GRAPES PINEAPPLES // This line should match.
9:load frmxyz // This line should match.
11:pears load frm grapes pineapples // This line should match.