Регулярные выражения (или если сокращенно “регэкспы” (regexp, regular expressions)) обладают огромной мощью, и способны сильно упростить жизнь системного администратора или программиста.
Однако в мире системного администрирования Windows они мало известны и непопулярны — в cmd.exe практически единственная возможность их применения это утилита findstr.exe, которая обладает очень маленьким функционалом и использует жутко урезанный диалект регулярных выражений. В VBScript функционал регулярных выражений тоже хорошо запрятан, и практически не используется. А вот в PowerShell, авторы языка позаботились о том чтобы регулярные выражения были легко доступны, удобны в использовании и максимально функциональны. Тем более что с последним пунктом всё оказалось достаточно просто — PowerShell использует реализацию регулярных выражений .NET, а она является одной из самых функциональных и производительных, и даже способна потягаться даже с признанным лидером в этой области — perl’ом.
Что же такое регулярные выражения? Регулярные выражения это специальный мини-язык служащий для разбора (parsing) текстовых данных. С его помощью можно разделять строки на компоненты, выбирать нужные части строк для дальнейшей обработки, производить замены, и всё это с огромной гибкостью и точностью.
Впрочем… знакомство с регулярными выражениями лучше начать не с них, а с более простой технологии служащей подобным целям, с которой знакомы все Windows администраторы – с подстановочных символов. Наверняка вы не раз выполняли команду dir, и указывали ей в качестве аргумента маску файла, например *.exe. В данном случае звёздочка означает “любое количество любых символов”. Аналогично можно использовать и знак вопроса, он будет означать “один любой символ”, то есть dir ??.exe
выведет все файлы с расширением .exe и именем из двух символов. В PowerShell’овской реализации подстановочных символов можно применять и еще одну конструкцию — группы символов. Так например [a-f]
будет означать “один любой символ от a
до f
(a,b,c,d,e,f)”, а [smw]
любую из трех букв (s
, m
или w
). Таким образом команда get-childitem [smw]??.exe
выведет файлы с расширением .exe
, у которых имя состоит из трех букв, и первая буква либо s
, либо m
, либо w
. Неплохо, неправда ли? Так вот, по сравнению с возможностями регулярных выражения — это детский лепет. Но начнём с малого.
Для начала изучения мы будем использовать оператор PowerShell -match
, который позволяет сравнивать текст слева от него, с регулярным выражением справа. В случае если текст подпадает под регулярное выражение, оператор выдаёт True
, иначе — False
.
PS C:\> "PowerShell" -match "Power" True
Вы наверное обратили внимание, что при сравнении с регулярным выражением ищется лишь вхождение строки, полное совпадение текста необязательно (разумеется это можно изменить, но об этом позже). То есть достаточно чтобы регулярное выражение встречалось в тексте.
PS C:\> "Shell" -match "Power" False PS C:\> "PowerShell" -match "rsh" True
Еще одна тонкость: оператор -match
по умолчанию не чувствителен к регистру символов (как и другие текстовые операторы в PowerShell), если же вам нужна чувствительность к регистру, используйте -cmatch
:
PS C:\> "PowerShell" -cmatch "rsh" False
В регулярных выражениях можно использовать и группы символов:
PS C:\> Get-Process | where {$_.name -match "sy[ns]"} Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 165 11 2524 8140 79 0,30 5228 mobsync 114 10 3436 3028 83 50,14 3404 SynTPEnh 149 11 2356 492 93 0,06 1592 SynTPStart 810 0 116 380 6 4 System
И диапазоны в этих группах:
PS C:\> "яблоко","апельсин","груша","абрикос" -match "а[а-п]" апельсин абрикос
Кстати тут я в левой части оператора -match
поместил массив строк, и он соответственно вывел лишь те строки, которые подошли под регулярное выражение.
Разумеется перечисления символов можно комбинировать, например группа [агдэ-я]
будет означать “А или Г или Д или любой символ от Э до Я включительно”. Но гораздо интереснее использовать диапазоны для определения целых классов символов. Например [а-я]
будет означать любую букву русского алфавита, а [a-z]
английского. Аналогично можно поступать с цифрами — следующая команда выведет все процессы в именах которых встречаются цифры:
PS C:\> Get-Process | where {$_.name -match "[0-9]"} Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 93 10 1788 2336 70 1,25 548 FlashUtil10c 158 12 6500 1024 96 0,14 3336 smax4pnp 30 6 764 160 41 0,02 3920 TabTip32
Так как эта группа используется достаточно часто, для неё была выделена специальная последовательность — \d
(от слова digit). По смыслу она полностью идентична [0-9]
, но гораздо короче ????
PS C:\> Get-Process | where {$_.name -match "\d"} Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName ------- ------ ----- ----- ----- ------ -- ----------- 93 10 1788 2336 70 1,25 548 FlashUtil10c 158 12 6500 1024 96 0,14 3336 smax4pnp 30 6 764 160 41 0,02 3920 TabTip32
Так же последовательность была выделена для группы “любые буквы любого алфавита, любые цифры, или символ подчеркивания” эта группа обозначается как \w
(от word) она примерно эквивалентна конструкции [a-zа-я_0-9]
(в \w
еще входят символы других алфавитов которые используются для написания слов).
Еще вам наверняка встретится другая популярная группа: \s
— “пробел, или другой пробельный символ” (например символ табуляции). Сокращение от слова space. В большинстве случаев вы можете обозначать пробел просто как пробел но эта конструкция добавляет читабельности регулярному выражению.
Не менее популярной группой можно назвать символ .
(точка). Точка в регулярных выражениях аналогична по смыслу знаку вопроса в подстановочных символах, то есть обозначает один любой символ.
Все вышеперечисленные конструкции можно использовать как отдельно, так и в составе групп, например [\s\d]
будет соответствовать любой цифре или пробелу. Если вы хотите указать внутри группы символ -
(тире/минус) то надо либо экранировать его символом \
(обратный слеш), либо поставить его в начале группы, чтобы он не был случайно истолкован как диапазон:
PS C:\> "?????","Word","123","-" -match "[-\d]" 123 -
Источник: https://xaegr.wordpress.com/2009/11/20/regexp-1-intro/#more-703