Регулярные выражения — Введение

Регулярные выражения (или если сокращенно “регэкспы” (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

Добавить комментарий

Ваш адрес email не будет опубликован.