Количественные модификаторы (квантификаторы) 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Количественные модификаторы (квантификаторы)



 

Обычно регулярные выражения гораздо сложнее, чем приведенные выше, и записывать их по одному символу было бы тяжеловато. Например, нужно отобрать строки, состоящие из четырех символов, каждый из которых может быть буквой от A до F или цифрой? Регулярное выражение могло бы выглядеть примерно так:

 

PS C:\> "af12","1FE0","1fz1","B009","C1212" -match "^[a-f\d][a-f\d][a-f\d][a-f\d]$"

af12

1FE0

B009

Не слишком то лаконично, не правда ли? К счастью всю эту конструкцию можно значительно сократить. Для этого в регулярных выражениях существует специальная конструкция – " количественные модификаторы " (квантификаторы). Эти модификаторы приписываются к любой группе справа, и определяют количество вхождений этой группы. Например, количественный модификатор {4} означает 4 вхождения. Посмотрим на приведенном выше примере:

PS C:\> "af12","1FE0","1fz1","B009","C1212" -match "^[a-f\d]{4}$"

af12

1FE0

B009

Данное регулярное выражение полностью эквивалентно предыдущему – "4 раза по [a-f\d]". Но этот количественный модификатор не обязательно жестко оговаривает количество повторений. Например можно задать количество как "от 4 до 6". Делается это указанием внутри фигурных скобок двух чисел через запятую – минимума и максимума:

PS C:\> "af12","1FE0","1fA999","B009","C1212","A00062","FF00FF9" -match "^[a-f\d]{4,6}$"

af12

1FE0

1fA999

B009

C1212

A00062

Если максимальное количество вхождений безразлично, например нужно указать "3 вхождения или больше", то максимум можно просто опустить (оставив запятую на месте), например "строка состоящая из 3х или более цифр":

PS C:\> "1","12","123","1234","12345" -match "^\d{3,}$"

Минимальное значение опустить нельзя, но можно просто указать единицу:

PS C:\> "1","12","123","1234","12345" -match "^\d{1,3}$"

Как и в случае с символьными группами, для особенно популярных значений количественных модификаторов, есть короткие псевдонимы:

+ (плюс), эквивалентен {1,} то есть, "одно или больше вхождений"

* (звездочка), то же самое что и {0,} или на русском языке – "любое количество вхождений, в том числе и 0"

? (вопросительный знак), равен {0,1} – "либо одно вхождение, либо полное отсутствие вхождений".

В регулярных выражениях, количественные модификаторы сами по себе использоваться не могут. Для них обязателен символ или символьная группа, которые и будут определять их смысл. Вот несколько примеров:

.+ Один или более любых символов. Аналог?* в простых подстановках (как в cmd.exe).

Следующее выражение выбирает процессы, у которых имя "начинается с буквы S, затем следует 1 или более любых символов, затем снова буква S и сразу после неё конец строки". Иначе говоря "имена которые начинаются и заканчиваются на S":

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

 

Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName

------ ----- ----- ----- ------ -- -----------

257 14 6540 5220 53 5,97 508 services

30 2 424 128 5 0,08 280 smss

\S* Любое количество символов не являющихся пробелами. Подобное выражение может совпасть и с ""(с пустой строкой), ведь под любым количеством подразумевается и ноль, то есть 0 вхождений – тоже результат.

PS C:\> "abc", "cab", "a c","ac","abdec" -match "a\S*c"

abc

ac

abdec

Заметьте, строка "ac" тоже совпала, хотя между буквами A и C вообще не было символов. Если заменить * на + то будет иначе:

PS C:\> "abc", "cab", "a c","ac","abdec" -match "a\S+c"

abc

abdec

 

бобры? (Это не вопрос, а регулярное выражение). Последовательность "бобр", после которой может идти символ "ы", а может и отсутствовать:

PS C:\> "бобр","бобры","бобрята" -match "^бобры?$"

бобр

бобры

 

1.10.5. Группы захвата и переменная $matches

 

Теперь, когда мы можем с помощью регулярных выражений описывать и проверять строки по достаточно сложным правилам, пора познакомится с другой не менее важной возможностью регулярных выражений – "группами захвата" (capture groups). Как следует из названия, группы можно использовать для группировки. К группам захвата, как и к символам и символьным группам, можно применять количественные модификаторы. Например, следующее выражение означает "Первая буква в строке – S, затем одна или больше групп, состоящих из “знака - (минус) и любого количества цифр за ним” до конца строки":

PS C:\> "S-1-5-21-1964843605-2840444903-4043112481" -match "^S(-\d+)+$"

True

Или:

PS C:\> "Ноут","Ноутбук","Лептоп" -match "Ноут(бук)?"

Ноут

Ноутбук

Эти примеры показывают, как можно использовать группы захвата для группировки, но это вовсе не главное их качество. Гораздо важнее то, что часть строки, подпавшая под подвыражение, находящееся внутри такой группы, помещается в специальную переменную – $matches. $Matches - это массив, и в нем может находится содержимое нескольких групп. Причем под индексом 0 туда помещается вся совпавшая строка, начиная с единицы идет содержимое групп захвата. Рассмотрим пример:

PS C:\> "At 17:04 Firewall service was stopped." -match "(\d\d:\d\d) (\S+)"

True

PS C:\> $matches

 

Name Value

---- -----

2 Firewall

1 17:04

0 17:04 Firewall

Под индексом 0 находится вся часть строки, подпавшая под регулярное выражение, под 1 находится содержимое первых скобок, и под 2 соответственно содержимое вторых скобок. К содержимому $matches можно обращаться как к элементам любого другого массива в PowerShell:

PS C:\> $matches[1]

17:04

PS C:\> $matches[2]

Firewall

Если в строке присутствует много групп захвата, то бывает полезно дать им имена, это сильно облегчает дальнейшую работу с полученными данными:

PS C:\> "At 17:04 Firewall service was stopped." -match "(?<Время>\d\d:\d\d) (?<Служба>\S+)"

True

 

PS C:\> $matches

Name Value

---- -----

Время 17:04

Служба Firewall

0 17:04 Firewall

 

PS C:\> $matches.Время

17:04

PS C:\> $matches["Служба"]

Firewall

Регулярное выражение конечно усложнилось, но зато работать с результатами гораздо приятнее. Синтаксис именования следующий:

(?<Название Группы>подвыражение)

Не перепутайте порядок, сначала следует знак вопроса. Количественные модификаторы, в том числе? могут применяться только после группы, и следовательно в начале подвыражения – бессмысленны. Поэтому в группах знак вопроса, следующий сразу за открывающей скобкой, означает особый тип группы, в нашем примере – именованную.

Другой тип группы, который часто используется – незахватывающая группа. Она может пригодиться в тех случаях, когда не нужно захватывать содержимое группы, а надо применить её только для группировки. Например, в вышеприведённом примере с SID, такая группа была бы более уместна:

PS C:\> "S-1-5-21-1964843605-2840444903-4043112481" -match "^S(?:-\d+)+$"

True

PS C:\> $matches

 

Name Value

---- -----

0 S-1-5-21-1964843605-2840444903-4043112481

Синтаксис такой группы: (?:подвыражение). Группы можно и вкладывать одну в другую:

PS C:\> "MAC address is '00-19-D2-73-77-6F'." -match "is '([a-f\d]{2}(?:-[a-f\d]{2}){5})'"

True

PS C:\> $matches

 

Name Value

---- -----

1 00-19-D2-73-77-6F

0 is '00-19-D2-73-77-6F'

 

 

Управляющие инструкции

1.11.1. Инструкция If …ElseIf … Else

 

В общем случае синтаксис инструкции If имеет вид

If (условие1)

{блок_кода1}

[ElseIf (условие2)]

{блок_кода2}]

[Else

{блок_кода3}]

При выполнении инструкции If проверяется истинность условного выражения условие1.

Если условие1 имеет значение $True, то выполняется блок_кода1, после чего выполнение инструкции if завершается. Если условие1 имеет значение $False, проверяется истинность условного выражения условие2. Если условие2 имеет значение $True, то выполняется блок_кода2 и выполнение инструкции if завершается. Если и условие1, и условие2 имеют значение $False, то выполняется блок_кода3 и выполнение инструкции if завершается.

Пример использования инструкции if в интерактивном режиме работы. Сначала переменной $a присвоим значение 10:

PS C:\> $a=10

Затем сравним значение переменной с числом 15:

PS C:\> If ($a –eq 15) {

>> ‘Значение $a равно 15’

>> }

>> Else {‘ Значение $a не равно 15‘}

>>

Значение $a не равно 15

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

 

1.11.2. Циклы While и Do … While

Самый простой из циклов PS – цикл While, в котором команды выполняются до тех пор, пока проверяемое условие имеет значение $True. Инструкция While имеет следующий синтаксис:

While (условие) {блок_команд}

Цикл Do … While похож на цикл While, однако условие в нем проверяется не до блока команд, а после: Do {блок_команд} While (условие). Например:

PS C:\> $val=0

PS C:\>Do {$val++; $val} While ($val –ne 3)

 

Цикл For

 

Обычно цикл For применяется для прохождения по массиву и выполнения определенных действий с каждым из его элементов. Синтаксис инструкции For:

For (инициация; условие; повторение) {блок_команд}. Пример

PS C:\> For ($i=0; $i –lt 3; $i++) {$i }

 

Цикл ForEach

 

Инструкция ForEach позволяет последовательно перебирать элементы коллекций. Самый простой тип коллекции – массив. Особенность цикла ForEach состоит в том, что его синтаксис и выполнение зависят от того, где расположена инструкция ForEach: вне конвейера команд или внутри конвейера.



Поделиться:


Последнее изменение этой страницы: 2017-02-06; просмотров: 360; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.206.13.112 (0.045 с.)