Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Only word characters found.




 

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

 

$text = "аbс";

if($text=~ /^[A-Za-z]+$/)

{ print "Only letter characters found.\n";}

Qnly letter characters found.

 

Наконец, для проверки, что текст является идентификатором, то есть начинаетcя с буквы и содержит буквы, цифры и символы подчеркивания, можно использовать команду:

 

$text = "X125c";

if($text=~ /^[A-Za-z]\w+$/)

{ print "This is identifier.\n";}

This is identifier.

 

Как найти множественные совпадения

Для поиска нескольких вхождений шаблона можно использовать модификатор g. Следующий пример, который мы уже видели ранее, использует команду m/.../ с модификатором g для поиска всех вхождений буквы x в тексте:

 

$text="Here is texxxxxt";

while($text=~m/x/g){

print "Found another x.\n";

}

Found another x.

Found another x.

Found another x.

Found another x.

Found another x.

 

Модификатор g делает поиск глобальным. В данном (скалярном) контексте perl помнит, где он остановился в строке при предыдущем поиске. Следующий поиск продолжается с отложенной точки. Без модификатора g команда m/.../ будет упорно находить первое вхождение буквы х, и цикл будет продолжаться бесконечно.

В отличие от команды m/.../ команда s/.../.../ с модификатором g выполняет глобальную замену за один раз, работая так, будто внутри нее уже имеется встроенный цикл поиска, подобный приведенному выше. Следующий пример за один раз заменяет все вхождения х на z:

 

$text = "Here is texxxxxt.";

$text =~ s/x/z/g;

print $text;

Here is tezzzzzt.

Без модификатора g команда s/.../.../ заменит только первую букву х. Команда s/.../.../ возвращает в качестве значения число сделанных подстановок, что может оказаться полезным:

$text= "Here is texxxxxt.";

print (text =~ s/x/z/g)

5

 

Поиск нечувствительных к регистру совпадений

 

Вы можете использовать модификатор i, чтобы сделать поиск нечувствительным к разнице между заглавными и строчными буквами. В следующем примере программа повторяет на экране введенный пользователем текст до тех пор, пока не будет введено Q, или q (сокращение для QUIT или quit), после чего программа прекращает работу:

 

while(<>){

chomp;

unless (/^q$/i){

Print

}

else {

exit;

}

}

 

Выделение подстроки

Чтобы получить найденную подстроку текста, можно использовать круглые скобки в теле шаблона. Если это более удобно, можно также использовать встроенную функцию substr. В следующем примере мы вырезаем из текстовой строки нужный нам тип изделия:

 

$record = "Product number:12345

      Product type: printer

                   Product price: $325";

if($record=~/Product type:\s*([a-z]+)/i){

print "The product's type Is^$1.\n";

}

Product's type is printer.

Вызов функций и вычисление выражений при подстановке текста

 

Используя для команды s/.../.../модификатор е, вы тем самым показываете, что правый операнд (то есть подставляемый текст) - это то выражение perl, которое надо вычислить. Например, с помощью встроенной функции perl uc (uppercase) можно заменить все строчные буквы слов строки на заглавные:

 

$text = "Now is the time.";

$text=~ s/(\w+)/uc($1)/ge;

print $text;

NOW IS THE TIME.

Вместо функции uc($l) можно поместить произвольный код, включая вызовы программ.

 

Поиск n-го совпадения

 

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

 

$text = "Name:Anne Nanie:Burkart Name:Glaire Name: Dan";

while ($text =~ /Name: \s*(\w+)/g){

++$match;

print "Match number $match is $1.\n";

}

Match number 1 is Anne

Match number 2 is Burkart

Match number 3 is Claire

Match number 4 is Dan

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

 

$text = "Name:Anne Name:Burkart Name:Ciaire Name:Dan";

for ($match = 0;

$text =~ /Name:\s*(\w+)/g;

        print "Match number ${\match} is $1.\n")

{}

Match nuwber 1 Is Anne

Match number 2 is Burkart

Match number 3 is Claire

Match number 4 is Dan

 

Если же вам требуется определить нужное совпадение не по номеру, а по содержанию (например, по первой букве имени пользователя), то вместо счетчика $match можно анализировать содержимое переменной $1, обновляемой при каждом найденном совпадении. Когда требуется не найти, а заменить второе или третье вхождение текста, можно применить ту же схему, использовав в качестве тела цикла выражение perl, вызываемое для вычисления заменяющей строки:

 

$text = "Name:Anne Name:Burkart Name:Claire Name:Dan";

$match =0;

$text =~ s/(Name:\s*(\w+))/ # начинаетсякод perl

if (++$match == 2) # увеличить счетчик

                   {"Name:John ($2)"}# вернуть новое значение

    else {$1}       # оставить старое значение

    /gex;

print $text; 

Name:Anne Name:John (Burkart) Name:ClaireName:Dan

В процессе глобального поиска при каждом найденном совпадении вычисляется выражение, указанное в качестве второго операнда. При его вычислении увеличивается значение счетчика, и в зависимости от него в качестве замены подставляется либо старое значение текста, либо новое. Модификатор х позволяет добавить в поле шаблона комментарии, делая код более прозрачным. Обратите внимание, что нам пришлось заключить весь шаблон в круглые скобки, чтобы получить значение найденного текста и подставить его на прежнее место полностью.

16. Как ограничить "жадность" квантификаторов

 

По умолчанию квантификаторы ведут себя как "жадные" объекты. Начиная с текущей позиции поиска, они захватывают самую длинную строку, которой может соответствовать регулярное выражение, стоящее перед квантификатором. Алгоритм перебора с возвратами, используемый perl, способен ограничивать аппетит квантификаторов, возвращаясь назад и уменьшая длину захваченной строки, если не удалось найти соответствия между текстом и шаблоном. Однако этот механизм не всегда работает так, как хотелось бы. Рассмотрим следующий пример. Мы хотим заменить текст "That is" текстом "That's". Однако в силу "жадности" квантификатора регулярное выражение ".*is" сопоставляется фрагменту текста от начала строки и до последнего найденного "is":

 

$text = "That is some text, isn't it?";

$text =~ s/.*is/That's/;

print $texts;

That'sn'tit?

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

  • *? - ноль или несколько совпадений,
  • +? - одно или несколько совпадений,
  • ?? - ноль совпадений или одно совпадение,
  • {n}? - ровно n совпадений,
  • {n,}? - по крайней мере n совпадений,
  • {n,m}? - совпадений по крайней мере n, но не более, чем m.

Обратите внимание, что смысл квантификатора от этого не меняется; меняется только поведение алгоритма поиска. Если в процессе сопоставления шаблона и текста прототип определяется однозначно, то алгоритм поиска с возвратами увеличит "жадность" такого квантификатора точно так же, как он ограничивает аппетит собрата. Однако если выбор неоднозначен, то результат поиска будет другим:

 

$text = "That is some text, isn't it?";

$text =~ s/.*?is/That's/;

print $texts;

That's some text, isn't it?

 










Последнее изменение этой страницы: 2018-04-12; просмотров: 402.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...