Search     or:     and:
 LINUX 
 Language 
 Kernel 
 Package 
 Book 
 Test 
 OS 
 Forum 
 iakovlev.org 
 Languages
 С
 GNU С Library 
 Qt 
 STL 
 Threads 
 C++ 
 Samples 
 stanford.edu 
 ANSI C
 Libs
 LD
 Socket
 Pusher
 Pipes
 Encryption
 Plugin
 Inter-Process
 Errors
 Deep C Secrets
 C + UNIX
 Linked Lists / Trees
 Asm
 Perl
 Python
 Shell
 Erlang
 Go
 Rust
NEWS
Последние статьи :
  Rust 07.11   
  Go 25.12   
  EXT4 10.11   
  FS benchmark 15.09   
  Сетунь 23.07   
  Trees 25.06   
  Apache 03.02   
  SQL 30.07   
  JFS 10.06   
  B-trees 01.06   
 
TOP 20
 Go Web ...603 
 2.0-> Linux IP Networking...354 
 Secure Programming for Li...294 
 2.6-> Kernel 2.6.17...226 
 William Gropp...222 
 Kamran Husain...221 
 Robbins 4...218 
 Advanced Bash Scripting G...211 
 Rodriguez 9...197 
 Rodriguez 6...195 
 Ethreal 1...193 
 UML 3...192 
 Стивенс 8...190 
 Daniel Bovet 2...189 
 Steve Pate 1...187 
 Steve Pate 3...186 
 Kamran Husain...184 
 Advanced Bash Scripting G...182 
 Rodriguez 8...179 
 Kernel Notes...176 
 
  01.03.2019 : 2682145 посещений 

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
Оставьте свой комментарий !

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

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