Регулярные выражения — Отрицательные группы и якоря

regexp-2Продолжаем разговор о регулярных выражениях. В предыдущем посте я рассказал об основах, а в этом рассмотрим некоторые более “продвинутые” конструкции регулярных выражений.

Предполагается что вы уже знаете как указать регулярному выр ажению какие символы и/или их последовательности должны быть в строке для совпадения. А что если вам нужно указать не те символы которые должны присутствовать, а те которых не должно быть? То есть если вам нужно вывести лишь согласные буквы, вы можете конечно их перечислить, а можете использовать и отрицательную группу с гласными, например:

PS C:\> "a","b","c","d","e","f","g","h" -match "[^aoueyi]"
b
c
d
f
g
h

"Крышка" в качестве первого символа группы символов означает именно отрицание. То есть на месте группы может присутствовать любой символ кроме перечисленных в ней. Для того чтобы включить отрицание в символьных группах (\d, \w, \s), не обязательно заключать их в квадратные скобки, достаточно… перевести их в верхний регистр🙂 Например \D будет означать "что угодно, кроме цифр", а \S "всё кроме пробелов"

PS C:\> "a","b","1","c","45" -match "\D"
a
b
c
PS C:\> "a","-","*","c","&" -match "\W"
-
*
&

Уже гораздо могущественнее обычных символов подстановки, не так ли?🙂 А ведь мы только начали изучать основы! Символьные группы позволяют нам указать лишь содержимое одной позиции, один символ находящийся в неопределенном месте строки. А что если нам надо например выбрать все слова которые начинаются с буквы w? если просто поместить эту букву в регулярное выражение, то оно совпадёт для всех строк где w вообще встречается, и не важно — в начале, в середине или в конце строки. В таких случаях на помощь приходят "якоря". Они позволяют производить сравнение начиная с определенной позиции в строке. ^ (крышка) является якорем начала строки, а $ (знак доллара) - обозначает конец строки. Не запутайтесь - ^ как символ отрицания используется лишь в начале группы символов, а вне группы - этот символ является уже якорем🙂 Да, да, авторам регулярных выражений явно не хватало специальных символов, и они по возможности, использовали их более чем в одном месте (о втором значении $ поговорим позже)🙂 Впрочем лучше посмотреть на примере:

PS C:\> Get-Process | where {$_.name -match "^w"}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     80      10     1460        156    47     0,11    452 wininit
    114       9     2732       1428    55     0,56   3508 winlogon
    162      11     3660       1652    44     0,14   3620 wisptis
    225      20     5076       4308    95    31,33   3800 wisptis
    469      28     9572      11904   101     3,23   1844 wlcrasvc
    706      54    52452      43008   632     9,64   1072 wmdc
    105      10     2308       1428    76     0,08   4056 wuauclt

Эта команда вывела процессы у которых сразу после начала имени (^) следует символ w. Иначе говоря имя начинается на w. Давайте для усложнения примера, и для упрощения понимания, добавим сюда “крышку” в значении отрицательной группы:

PS C:\> Get-Process | where {$_.name -match "^w[^l-z]"}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
     80      10     1460        156    47     0,11    452 wininit
    114       9     2732       1428    55     0,56   3508 winlogon
    162      11     3660       1652    44     0,14   3620 wisptis
    225      20     5076       4308    95    31,50   3800 wisptis

Теперь команда вывела нам процессы у которых имя начинается с символа w, а следующий символ является чем угодно, только не из диапазона l-z.

Обратите внимание, примеры уже начинают походить на краказябли, а вы их уже можете понимать🙂

Ну и для закрепления, опробуем второй якорь — конец строки:

PS C:\> "Яблоки","Груши","Дыня","Енот","Апельсины","Персик" -match "[ыи]$"
Яблоки
Груши
Апельсины

Это выражение вывело нам все слова в которых последняя буква И или Ы.

Если вы можете точно описать содержимое всей строки, то вы можете использовать и оба якоря одновременно:

PS C:\> "abc","adc","aef","bca","aeb","abec","abce" -match "^a.[cb]$"
abc
adc
aeb

Это регулярное выражение выводит все строки которые начинаются с буквы А, за которой следует один любой символ (точка), затем символ C или B и затем конец строки.

Продолжение: Квантификаторы

комментариев 13 to “Регулярные выражения — Отрицательные группы и якоря”

  1. Юрий Says:

    Спасибо за статью.

    Меня вот смущает, что набор g*45 соответствует как строке «fgd 3456» так и строке «3456 fgd». Как-то это у меня не укладывается совсем в голове.

    • Xaegr Says:

      Более того, он будет соответствовать любой строке в которой встречается 45, независимо от других факторов и наличия буквы «g»🙂 g* может соответствовать как «g», так «ggggg» так и нулю g, то есть «». Подробнее в следующих постах🙂

      • Юрий Says:

        Век живи — век учись. Всё это время для меня * существовала сама по себе (а + и вовсе не пользовал я), без предшествующего символа. В файловых масках я имею ввиду. Больше нигде ей и не пользовался.
        Вообщем жду следующую статью с нетерпением. )

  2. abigor Says:

    жгешь редиско

    • Xaegr Says:

      Чойта я редиско?😉 Я очень даже хороший человек🙂 И очень скромный само-собой😉

  3. Регулярные выражения – Количественные модификаторы (квантификаторы) « PowerShell и другие скрипты Says:

    […] процесса на удалённом компьютере – WinRM (WS-Management)Регулярные выражения — Отрицательные группы и якоряПростенькая инвентаризация ПО на компьютерахЗапуск […]

  4. Группы захвата « PowerShell и другие скрипты Says:

    […] Отрицательные группы и якоря […]

  5. Регулярные выражения – Жадность « PowerShell и другие скрипты Says:

    […] Регулярные выражения – Жадность 24.12.2009 — Xaegr Просто отличное название для очередной статьи о регулярных выражениях в блоге посвященном PowerShell Но оно действительно подходит лучше всего. Сегодня мы поговорим об одной важной концепции регулярных выражений. От чего зависит сколько символов будет захвачено количественным модификатором с варьирующейся длинной? Именно от жадности Если вы наткнулись на пост случайно, то сначала лучше ознакомьтесь с предыдущими постами серии – 1,2,3,4,5. […]

  6. Регулярные выражения – Select-String « PowerShell и другие скрипты Says:

    […] разумеется Мы успели познакомится с основами, отрицательными группами и якорями, квантификаторами, группами захвата, операторами […]

  7. Юрий Says:

    А могу ли я как-либо обозначить отрицательное слово, кроме как перечислением вида [^w][^o][^r][d^] ?

    • Xaegr Says:

      Да, конечно. Например с помощью незахватывающей группировки:
      PS D:\Temp> «word» -match «^(:?^word)$»
      True
      PS D:\Temp> «wort» -match «^(:?^word)$»
      False
      Но иногда проще использовать оператор -notmatch🙂

  8. Регулярные выражения – Switch « PowerShell и другие скрипты Says:

    […] на посты которые рекомендуется прочитать сначала: 1, 2, 3, 4, 5, 6, […]


Обсуждение закрыто.

%d такие блоггеры, как: