Главная

Wednesday, 8 April 2020

Регулярные выражения в PowerShell #2.

Всем привет.

Сегодня еще кое что из книги "Keith Hill, Эффективное программирование в Windows PowerShell. 2009". На сей раз еще раз про регулярные выражения. 

Известно что PowerShell основан на .NET Framework. То есть, он построен с использованием .NET Framework и предоставляет возможности .NET Framework пользователю. Одна из наиболее удобных возможностей в .NET Framework - класс Regex в пространстве имён System.Text.RegularExpressions. Это очень мощный механизм регулярных выражений. PowerShell использует его в ряде сценариев с помощью:
• оператора -match
• оператора -notmatch
• параметра -Pattern командлета Select-String.

Конечно,   чтобы   использовать   эти   операторы   и   Select-String   максимально   эффективно, необходимо хорошо понимать применение регулярных выражений. Справочная система PowerShell содержит раздел с именем "about_Regular_Expression", который вы можете вызвать так:
PS> help about_reg*

Данный раздел представляет собой лишь краткое справочное руководство по различным метасимволам, с его помощью вы не научитесь создавать мощные регулярные выражения. Чтобы узнать, как получить максимальную отдачу от регулярных выражений, и, следовательно, PowerShell, я очень рекомендую прочитать книгу Jeffrey Friedl Mastering Regular Expressions (Джеффри Фридл, Регулярные выражения). В   механизме   поддержки   регулярных   выражений   PowerShell   существует   один   недостаток,   который необходимо знать. Большинство других скриптовых языков поддерживают синтаксис, позволяющий обнаружить все вхождения шаблона в строке. Например, в Perl я могу сделать так:

$_ = "paul xjohny xgeorgey xringoy stu pete brian"; # PERL script
($first, $second, $third) = /x(.+?)y/g;

К сожалению, командлет Select-String не поддерживает эту возможность в версии 1.0. Тем не менее, вы можете обойти это ограничение, используя класс System.Text.RegularExpressions.Regex напрямую. Нет необходимости   указывать   имя   класса   полностью,   PowerShell   имеет   для   него   псевдоним   [regex]. 

Например:
PS> $str = "paul xjohny xgeorgey xringoy stu pete brian"
PS> $first,$second,$third = ([regex]'x(.+?)y').Matches($str) |
>>Foreach {$_.Groups[1].Value}
PS> $first
john
PS> $second
george
PS> $third
ringo

Одна из вещей, за которой необходимо тщательно следить - написание регулярного выражения для поиска во всей строке. Например, вы решили использовать Get-Content для получения содержимого файла и применения к нему регулярного выражения. В этом случае необходимо помнить, что Get-Content считывает файл частями - строка за строкой. Для применения регулярного выражения ко всему содержимому файла, необходимо будет преобразовать это содержимое в одну строку. Я могу сделать это в PowerShell 1.0, например, так:

PS> $regex = [regex]'(?<CMultilineComment>/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
PS> Get-Content foo.c | Join-String -Newline | Foreach {$regex.Matches($_)} |
>> Foreach {$_.Groups["CMultilineComment"].Value}
>>

Здесь я использовал командлет Join-String, разработанный PowerShell Community Extensions, который принимает отдельные строки, выводимые Get-Content, и создаёт из них одну строку. Также в примере использован именованный захват CMultilineComment. Этот пример демонстрирует, что при отсутствии возможностей в самом PowerShell, использование среды .NET может стать замечательным "запасным выходом".

Начиная с версии PowerShell 2.0 появились новые возможности, помогающие выполнять поиск в вышеописанном случае. Во-первых,   добавлен   оператор   объединения,   с   помощью   которого   можно   соединять  многострочный текст в одну строку. Во-вторых, в Select-String появились новые параметры, такие как -Context, -NotMatch и -AllMatches. Параметр AllMatches как раз подходит для решения предыдущей задачи. Вот как можно теперь выполнить поиск комментариев:

$pattern = '(?<CMultilineComment>/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
PS> (get-content .\foo.c) -join "`n" | Select-String $pattern -all |
>>Foreach {$_.Matches} | Foreach {$_.Value}

Использование   регулярных   выражений   -   очень   мощный   инструмент   PowerShell.   Научитесь   его использовать, и он откроет вам много возможностей поиска и обработки текстовых данных.

No comments:

Post a Comment

А что вы думаете по этому поводу?