Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
iakovlev.org

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

Регулярные выражения позволяют сопоставлять текст с указанным шаблоном (а именно, сравнивать две строки с помощью универсальных символов, интерпретируемых специальным образом) и выполнять замену текста.
 	В Perl имеются три основных оператора, работающих со строками:
 	# m/.../ — проверка совпадений (matching),
 	# s/.../.../ — подстановка текста (substitution),
 	# tr/.../.../ — замена текста (translation).
Оператор m/.../ анализирует входной текст и ищет в нем подстроку, совпадающую с указанным шаблоном. Оператор s/.../.../ выполняет подстановку одних текстовых фрагментов вместо других. Оператор tr/.../.../ осуществляет замену посимвольно.
  В следующем примере ищем подстроку exit :
 	if ($line =~ m/exit/i) {exit;}
Префикс /i указывает на то , что регистр символов в переменной $line не имеет значения. Начальную букву m в операторе сравнения можно опустить. Можно использовать вместо / другие разграничители , но тогда прийдется писать m :
 	if ($line =~ /exit/i) {exit;}
 	if ($line =~ m|quit|i) {exit;}
 	if ($line =~ m%stop%i) {exit;}
 
В следующем случае мы заменяем подстроку young на подстроку old:
 	$text = "Pretty young.";
 	$text =~ s/young/old/;
Операторы s/.../.../ и m/.../ ведут поиск и замену с первого символа текстовой строки до первого совпадения. Если оно найдено, без специального указания поиск не продолжается:
  Оператор tr/.../.../ заменяет один символ на другой ,
 	$text = "His name is Tom.";
 	$text =~ tr/o/i/;
  
В Perl операторы tr/.../.../ и y/.../.../ выполняют одинаковые действия

Рассмотрим регулярные выражения . В общем случае они состоят из следующих компонентов :
 	# одиночные символы (characters)
 	# классы символов (character classes)
 	# альтернативные шаблоны (alternative match patterns)
 	# квантификаторы (quantifiers)
 	# мнимые символы (assertions)
 	# ссылки на найденный текст (backreferences)
 	# дополнительные конструкции (regular expression extensions).
  
Perl определяет специальные символы. Они вводятся с помощью обратной косой черты (escape-последовательности) и также могут встречаться в регулярном выражении:
 	# \077 — восьмиричный символ
 	# \a — символ BEL (звонок)
 	# \c[ — управляющие символы (комбинация Ctrl + символ, 
                 в данном случае — это управляющий символ ESC)
 	# \d — соответствует цифре
 	# \D — соответствует любому символу, кроме цифры
 	# \e — символ escape (ESC)
 	# \E — конец действия команд \L, \U и \Q
 	# \f — символ прогона страницы (FF)
 	# \l — следующая литера становится строчной (lowercase)
 	# \L — все последующие литеры становятся строчными вплоть до команды \E
 	# \n — символ новой строки (LF, NL)
 	# \Q — вплоть до команды \E все последующие метасимволы становятся 
                 обычными символами
 	# \r — символ перевода каретки (CR)
 	# \s — соответствует любому из пробельных символов 
  (пробел,вертикальная или горизонтальная табуляция,символ новой строки)
 	# \S — любой символ, кроме «пробельного»
 	# \t — символ горизонтальной табуляции (HT, TAB)
 	# \u — следующая литера становится заглавной (uppercase)
 	# \U — все последующие литеры становятся заглавными вплоть до команды \E
 	# \v — символ вертикальной табуляции (VT)
 	# \w — алфавитно-цифровой символ (любая буква, цифра или символ подчеркивания)
 	# \W — любой символ, кроме букв, цифр и символа подчеркивания
 	# \x1B — шестнадцатиричный символ
В следующем примере Here будет заменено на There с помощью шаблона \w+
 	$text = "Here is some text.";
 	$text =~ s/\w+/There/;
 	print $text;
 	There is some text.
С помощью символа точка все символы в строке заменяются на звездочку :
 	$text = "Now is the time.";
 	$text =~ s/./*/g; 
Символы могут быть сгруппированы в классы .Класс - список символов , заключенный в квадратные скобки . Можно указывать как отдельные символы , так и диапазон Следующий код производит поиск гласных :
 	$text = "Here is the text.";
 	if ($text =~ /[aeiou]/) {print "Yesss.\n";}
C помощью шаблона [A-Za-z]+ (метасимвол + означает утверждение: «один или более таких символов» ) ищется и заменяется первое слово:
 	$text = "What is the subject.";
 	$text =~ s/[A-Za-z]+/Perl/;
 	print $text;
 	Perl is the subject.
Если сразу после открывающей квадратной скобки стоит символ ^, то смысл меняется на противоположный - а именно, этот класс сопоставляется любому символу, кроме перечисленных в квадратных скобках. В следующем примере производится замена фрагмента текста, составленного не из букв и не из пробелов:
 	$text = "Perl is the subject on page 493 of the book.";
 	$text =~ s/[^A-Za-z\s]+/500/;
 	print $text;
 	Perl is the subject on page 500 of the book.
Вы можете задать несколько альтернативных шаблонов, используя символ | как разделитель. Например, следующий фрагмент проверяет на «exit», «quit» или «stop» одновременно:
    if ($line =~ m/exit|quit|stop/) {exit;}
Конструкция [Tim|Tom|Tam] будет эквивалентна классу символов [Tioam|].

Квантификаторы указывают на то, что тот или иной шаблон в строке может повторяться определенное количество раз. Например, можно использовать квантификатор + для поиска мест неоднократного повторения подряд латинской буквы e и их замены на одиночную букву e:
 	$text = "Hello from Peeeeeeeeeeeeeeerl.";
 	$text =~ s/e+/e/;
 	print $text;
 	Hello from Perl.
Проверка на то , что в строке не менее 20 символов :
   if ($line =~ !m/.{20,}/) {print "Please type longer lines!\n";} 
В Perl имеются символы (метасимволы), которые соответствуют не какой-либо литере или литерам, а означают выполнение определенного условия (поэтому в английском языке их называют assertions,или утверждениями).
 	# . — соответствует любому символу кроме новой строки
 	# ^ — начало строки текста,
 	# * — совпадение 0 или более раз
 	# + — совпадение 1 или более раз
 	# ? — совпадение 0 или 1 раз
 	# (n) — совпадение точно n раз
 	# (n,) — совпадение меньше или равно n раз
 	# (n,m) — совпадение минимум n раз но не более чем m раз
 	# | — чередование (соответствует "left|right|up|down|sideways")
 	# $ — конец строки или позиция перед символом начала новой строки, 
         расположенного в конце,
 	# \b — граница слова,
 	# \B — отсутствие границы слова,
 	# \A — «истинное» начало строки,
 	# \Z — «истинный» конец строки или позиция перед символом 
         начала новой строки, расположенного в «истинном» конце строки,
 	# \z — «истинный» конец строки,
 	
 Пример:
 Пусть у нас имеется список :
 	Anne Bonney
 	Bartholomew Roberts
 	Charles Bellamy
 	Diego Grillo
 	Edward Teach
 	Francois Gautier
 	George Watling
 	Henry Every
 	Israel Hands
 	John Derdrake
 	KuoHsing Yeh 	
В каждой строке этого списка требуется заменить 1-е слово на 'Captain'.
 	s/^.+ /Captain /;
В данном решении символ ^ соответствует началу строки , .+" - для каждого символа более 1 раза, Теперь посложнее - поменяем в каждой строке имя и фамилию , и в начале каждой строки будет идти Captain :
 	s/^(\w*) (\w*)$/Captain $2, $1/;
Пример:
   Рассмотрим фразу :
   Acciones son amores, no besos ni apachurrones	
Шаблон /A.*es/ будет соответствовать целиком всей этой фразе. А вот шаблон /A.*?es/ будет соответствовать Acciones

В следующем примере выводится сообщение о том, что переменная = «yes», при условии что оно единственное. Для этого шаблон включает мнимые символы начала и конца строки:
    if ($line =~m/^yes$/) {    print "Yesss.\n";
Следующий пример позволяет выделять текст, расположенный между любыми правильно закрытыми метками:
 $text = "Here is an anchor.";
 if ($text =~ m%<([A-Za-z]+)>[\w\s\.]+%i) {
    print "HTML tag with some text inside it is found.";}
Пример: разбить целое число на триады , т.е. разбить его на группы по 3 цифры , разделенные пробелом :
 $number=112341234526.24;
 $number=triada($number);
 print $number;
 sub triada() {  
  $str=$_[0];
  $res="";  
  if ($number=~m/^[0-9]{1,}$/) {  
   while (length($str)>3) {  
    $res=' '.substr($str,length($str)-3).$res;  
    $str=substr($str,0,length($str)-3);  
   }  
  }  
  $res=$str.$res;  
  return $res;  
 }   
Внутренние переменные можно использовать и вне шаблона, ссылаясь на них как на скаляры с именами $1, $2, $3, ... $n:
 	$text = "I have 4 apples.";
 	if ($text =~ /(\d+)/) {
 	print "Here is the number of apples: $1.\n";
 	}
 	Here is the number of apples: 4.
В следующем примере мы изменяем порядок трех слов в текстовой строке с помощью команды s/.../.../:
 	$text = "I see you.";
 	$text =~ s/^(\w+) *(\w+) *(\w+)/$3 $2 $1/;
 	print $text;
 	you see I.
В следующем примере мы последовательно заменим местами пары слов, заданных во входном тексте, оставив между ними по одному пробелу:
 	$text = "One   Two   Three   Four   Five   Six";
 	$text =~ s/(\w+)\s*(\w+)/$2 $1 /g;
 	Two One Four Three Six Five
Следующая команда подсчитывает количество букв x в заданной строке текста:
 	$text = "Here is texxxxxt.";
 	$counter = 0;
 	while ($text =~ m/x/g) {
 	print "Found another x.\n";
 	$conter++;
 	}
     Print "Total amount = $counter.\n";
 	Total amount = 5.
В следующем примере из текстовой строки последовательно извлекаются и выводятся пары имя/значение до тех пор, пока строка не закончится:
 	$text = "X=5; z117e=3.1416; temp=1024;";
 	$docycle = 1; $counter = 0;
 	while ($docycle) {
 	undef $name; undef $value;
 	if ($text =~ m/(\w+)\s*=\s*/g) {$name = $1;}
 	if ($text =~ m/([\d\.\+\-]*)\s*;/g) {$value = $1;}
 	if (defined($name) and defined($value)) {
 		print "Name=$name, Value=$value.\n";
 		$counter++;
 	} else {
 		$docycle = 0;
 	}
 	}
 	print "I have found $conter values.\n";
 	Name=X, Value=5.
 	Name=z117e, Value=3.1416.
 	Name=temp, Value=1024.
 	I have found 3 values.
В следующем примере из строки последовательно извлекаются буквы p, o и q и выводится текущая позиция поиска:
 	$index = 0;
 	$_ = "ppooqppqq";
 	while ($index++ < 2) {
 	print "1: ’";
 	print $1 while /(o)/gc; print "’, pos=", pos, "\n";
 	print "2: ’";
 	print $1 if /\G(q)/gc; print "’, pos=", pos, "\n";
 	print "3: ’";
 	print $1 while /(p)/gc; print "’, pos=", pos, "\n";
 	}
 	1: ’oo’, pos=4
 	2: ’q’, pos=5
 	3: ’pp’, pos=7
 	1: ’’, pos=7
 	2: ’q’, pos=8
 	3: ’’, pos=8
В следующем фрагменте кода, заменяющем строчные буквы на заглавные:
 	$text = "Here is the text.";
 	$text =~ tr/a-z/A-Z/;
 	print $text;
 	HERE IS THE TEXT.
Для замены заглавных букв на строчные и наоборот, достаточно выполнить команду:
 	$text = "MS Windows 95/98/NT";
 	$text =~ tr/A-Za-z/a-zA_Z/;
 	print $text;
 	ms wINDOWS 95/98/nt
Удаляем строчные латинские буквы и заменяем пробелы на слеши:
 	$text = "Here is the text.";
 	$text =~ tr[ a-z][/]d;
 	print $text;
 	H///.
Заменим на звездочки все символы, кроме строчных латинских букв:
 	$text = "Here is the text.";
 	$text =~ tr/a-z/*/c;
 	print $text;
 	*ere*is*the*text*
Заменим слова, состоящие из латинских букв, на однократные символы косой черты:
 	$text = "Here is the text.";
 	$text =~ tr(A-Za-z)(/)s;
 	print $text;
 	/ / / /.
Заменить множественные пробелы и нетекстовые символы на одиночные пробелы:
 	$text = "Here    is    the    text.";
 	$text =~ tr[\000-\040\177\377][\040]s;
 	print $text;
 	Here is the text.
Сократить удвоенные, утроенные и т.д. буквы:
 	$text = "Here is the texxxxxxt.";
 	$text =~ tr/a-zA-Z//s;
 	print $text;
 	Here is the text.
Пересчитать количество небуквенных символов:
 	$xcount=($text =~ tr/A-Za-z//c);
Обнулить восьмой бит символов, удалить нетекстовые символы:
 	$text =~ tr{\200-\377}{\000-\177};
 	$text =~ tr[\000-\037\177][]d;
Заменить нетекстовые и 8-ми битные символы на одиночный пробел:
 	$text =~ tr/\021-\176/ /cs;
Поиск отдельных слов Чтобы выделить слово, можно использовать метасимвол \S, соответствущий символам, отличным от «пробельных»:
 	$text = "Now is the time.";
 	$text =~ /(\S+)/;
 	print $1;
 	Now
Следующий код проверяет, действительно ли введенный текст представляет собой целое значение без знака и паразитных пробелов:
 	$text = "333";
 	if ($text =~ /^\d+$/) {
 	print "It is a number.\n";
 	}
 	It is a number.
Вы можете потребовать, чтобы число соответствовало привычному формату. То есть, число может содержать десятичную точку, перед которой стоит по крайней мере одна цифра и, возможно, какие-то цифры после нее:
 	$text = "3.1415926";
 	if ($text =~ /^(\d+\.\d*|\d+)$/) {
 	print "It is a number.\n";
 	}
 	It is a number.
 
 	$text = "-2.7182";
 	if ($text =~ /^([+-]*\d+(\.\d*|)$/) {
 	print "It is a number.\n";
 	}
 	It is a number.
 	
С помощью метасимвола \w можно проверить, состоит ли текст только из букв, цифр и символов подчеркивания (это те символы, которые Perl называет словными (word characters)):
 	$text = "abc";
 	if ($text =~ /^\w+$/) {
 	print "Only word characters found.\n";
 	}
 	Only word characters found.
Однако, если вы хотите убедиться, что текст содержит латинские буквы и не содержит цифр или символов подчеркивания, придется использовать другой шаблон:
 	$text = "aBc";
 	if ($text =~ /^[A-Za-z]+$/) {
 	print "Only letter characters found.\n";
 	}
 	Only letter characters found.
С помощью модификатора g перебраются все вхождения заданного шаблона.
 	$text = "Name:Anne Name:Burkart Name:Claire Name:Dan";
 	$match = 0;
 	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
Когда требуется не найти, а заменить второе или третье вхождение текста, можно использовать ту же схему, использовав в качестве тела цикла выражение Perl, вызываемое для вычисления заменяющей строки:
 	$text = "Name:Anne Name:Burkart Name:Claire Name:Dan";
 	$match = 0;
 	$text =~ s/(Name:\s*(\w+))/
 		if (++$match == 2)
 			{"Name:John ($2)"}
 		else {$1}
 	/gex;
 	print $text;
 	Name:Anne Name:John (Burkart) Name:Claire Name:Dan
Оставьте свой комментарий !

Ваше имя:
Комментарий:
Оба поля являются обязательными

 Автор  Комментарий к данной статье