Power Perl Education главная страница возможности Power Guest Book темы оформления настройка скрипта FAQ Download благодарности

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

Основные понятия.

Регулярное выражение представляет собой образец - шаблон - который сопоставляется со строкой. Сопоставление со строкой дает либо успешный результат, либо неудачный.

Основные направления использования регулярных выражений.

if(/abc/) {
	print $_;
}

В примере с регулярным выражением abc сравнивается переменная $_. Этот фрагмент Perl программы рассметривает только одну строку. Для обработки всех строк:

while(<>) {
	if(/abc/) {
		print $_;
	}
}

Пример:

while(<>) {
	if(/ab*c/) {
		print $_;
	}
}

Ищется последовательность, содержащая символ a, ни одного или более символа b и символ c.

Операция замены:

s/ab*c/def/;

Переменная ($_ в данном случае) сопоставляется с рег. выражением и с случае успеха заменяется строкой def.

Образцы.

Регулярное выражение - это образец.

Образцы, обозначающие один символ.

Одиночный символ соответствует самому себе. Символ точка - любой одиночный символ, кроме символа новой строки (\n). Например, образцу /a./ соответствует любая двухбуквенная поседовательность, начинающаяся с a.

Класс символов сопоставления:

/[abcde]	#	строка, содержащая любую из первых пяти строчных букв
/[aeiouAEIOU]	# -//- из первых пяти гласных

Диапазоны символов:

[0123456789]
[0-9]
[0-9\-]
[a-z0-9]
[a-zA-Z0-9_]

Отрицание класса символов:

[^0-9]
[^aeiouAEIOU]
[^\^]
Предопределенные классы символов
Конструкция Эквивалентный класс Конструкция с отрицанием Эквивалентный класс с отрицанием
\d (цифра) [0-9] \D (нецифровые символы) [^0-9]
\w (обычный символ) [a-zA-Z0-9_] \W (специальный символ) [^a-zA-Z0-9_]
\s (пробельный символ) [ \r\t\n\f] \S (непробельный символ) [^ \r\t\n\f]

Пример:


[\da-fA-F]	#	одна шестнадцатеричная цифра

Образцы, обозначающие группу символов.

Последовательности.

Например, образец abc.

Множители.

* - ни одного или более экземпляров стоящего непосредственно перед ней символа.

+ - один или более экземпляров стоящего непосредственно перед нем символа.

? - ни одного или один экземпляр стоящего непосредственно перед ним символа.

Например, регулярное выражение /fo+ba?r/ обозначает символ f, за которым следует один или более символов o, затем символ b, затем ни одного или один символ a и символ r.

$_ = "mike xxxxxxxxxxxxx nick"
s/x+/igor/;

В последнем примере все символы x будут заменемы на igor (описанные выше образцы характеризуются
" прожорливостью "). Простой способ избежать этого - применение общего множителя.

/x{5,10}/ - найти символ, стоящий перед скобками, повторяющийся от пяти до десяти раз.

/x{5,}/ - найти символ, стоящий перед скобками, повторяющийся от пяти раз.

/x{5}/ - найти символ, стоящий перед скобками, повторяющийся ровно пять раз.

/x{,5}/ - найти символ, стоящий перед скобками, пять раз или менее.

/a.{5}b/ - соответствует букве a, отделенной от буквы b любыми пятью символами.

Если в одном выражении используются два множителя, то правило " прожорливости" дополняется правилом "чем левее, тем прожорливее ". Например:

$_ = "a xxx c xxxxxxxx c xxx d";
/a.*c.*d/;

Первая комбинация ".*" соответствует всем символам до второй буквы c.

Можно заставить любой множитель перестать быть "прожорливым", поставив после него вопросительный знак:

$_ = "a xxx c xxxxxxxx c xxx d";
/a.*?c.*d/;

Теперь a.*?c соответствует манимальному числу символов между a и c, а не максимальному.

Круглые скобки как способ запоминания.

При совпадении с образцом никаких изменений не происходит, просто совпавшая часть строки запоминается, и к ней можно впоследствии обращаться. Например, (a) продолжает соответствовать букве a, а ([a-z]) - любой строчной букве.

Чтобы вызвать часть строки, который программа запомнила, нужно поставить косую черту и целое число.

/mike(.)igor\1/

Соответствует строке, состоящей из слова mike, любого символа, слова igor и еще одного такого же символа. Единица обозначает первую заключенную в круглые скобки часть регулярного выражения. Если таких частей больше, чем одни, то вторая обозначается как \2 ...

/a(.)b(.)c\2\1/;

Запоминаемая часть может состоять не только из одного символа.

/a(.*)b\1c/;

- a, любое количество символов, b, ту же последовательность символов, и c.

Дизьюнкция.

a|b|c - означает, что данный образец соответствует только одному из указанных вариантов. Такая конструкция работает и для класса символов, как в образце /igor|mike/.

Фиксирование образцов.

Некоторые особые виды записи позволяют фиксировать образец относительно позиции в строке, в кот. ищется соответствие.

Фиксирующая деректива \b требует, чтобы совпадение с образцом b происходило только на границе слова.

/fred\b/;	#	соответствует слову fred, но не Frederik
/\bmo/;		#	соответствует словам moe и mole, но не Elmo
/\bFred\b/;	#	соответствует слову Fred, но не Frederik или alFred
/\b\+\b/;	#	соответствует "x+y", но не "++" или " + "

\B требует, чтобы в указанной точке границы слова не было. Символ ^ обозначает начало строки. Символ $ фиксирует образец по концу строки.

Поддерживаются и другие фиксирующие точки.

Приоритет.

Приоритет групповых регулярных выражений.
НаименованиеОбозначение
Круглые скобки ( ) (?: )
Множители ? + * {m, n} ?? +? {m, n}?
Последовательность и фиксация abc ^ $ \A \Z (?= ) (?! )
Дизьюнкция |

Примеры:

abc*	#	ab, abc, abcc, abccc ...
(abc)*	#	"", ab, abc, abcabc, abcabcabc ...
^x|y	#	x в начале строки или y в любом месте
^(x|y)	#	x или  y в начале строки
a|bc|d	#	либо a, либо bc, либо d
(a|b)(c|d)	#	ac, ad, bc, или bd
(song|blue)bird	#	songbird или bluebird

Еще об операции сопоставления.

Выбор другого обьекта для сопоставления.

Если строка, которую нужно сопоставить с образцом, не находится в переменной $_, то можно воспользоваться операцией =~. Пример:

$a = " hello world";
$a =~ /^he/;			# истина
$a =~ /(.)\1/;			# истина (соответствует двум l)
if($a =~ /(.)\1/) {	#истина
}

Слева от знака операции =~ может стоять любое выражение:

print "any last request? ";
if( <STDIN> =~ /^[yY]/) {
	print "And just what might that request be? ";

	<STDIN>;
	print "Sorry, I'm unable to do that.\n";
}

Игнорирование регистра.

Игнорирование регистра /образец/i.
print "any last request? ";
if(<STDIN> =~ /^y/i) {
	...
}

Использование другого разделителя.

Для нахождения строки, которая содержит несколько символов (/), нужно перед каждым из них поставить обр. косую черту.
$path = <STDIN>;			# прочитать путь
if(path =~ /^\/usr\/etc/) {
	# начинается с /usr/etc...
}

Можно заменить разделитель, если перед любым специальным символом поставить букву m.
/^\/usr\/etc/
m@^/usr/etc@
m#^/usr/etc#

Использование интерполяции переменных.

Перед тем как регулярное выражение расспатривается, в нем производится интерполяция переменных
$what = "bird";
$sentence = "Every good bird does fly.";
if($sentence =~ /\b$what\b/) {
	print "The centence contains theword $what!\n";
}

Операция замены.

Простая форма операции замены: s/регулярное_выражение/новая_строка/ При всех возможных совпадениях:
$_ = "foot fool buffoon";
s/foo/bar/g;		# $_ -> "bart barl bufbarn"
В заменяущей строке производится интерполяция переменных
$_ = "hello, world!";
$new = "goodbye";
s/hello/$new/;
Можно ипользовать сопоставление с образцом
$_ = "this is a test";
s/(\w+)/<$1>/g;
При помощи операции =~ можно указать другой обьект для операции замены
$which = "this is a test";
$which =~ s/test/quiz/;

Функции split и join.

$line = "gds::*::1001::20::Samolyuk German::/home/gds::/usr/local/bin/tcsh";
@fields = split(/:/, $line);	# разбить $line, используя в качестве
				# разделителя двоеточие
# @fields содержит ("gds","","*","","1001","","20","","Samolyuk German","",
# "/home/gds","","/usr/local/bin/tcsh")
Второе поле : стало пустой строкой, если вы этого не хотите:
@fields = split(/:+/, $line);
Использование автоматической переменной:
$_ = "this is a some text";
@words = split(/ /);		# @words = split(/ /, $_);
Соседние пробелы вызовут появление пустых строк. Лучше использовать образец / +/ или /\s+/. Или по умолчанию:
@words = split;		# @words = split(/\s+/, $_);
Пример:
$line = "gds::*::1001::20::Samolyuk German::/home/gds::/usr/local/bin/tcsh";
($name, $password, $uid, $gid, $gcos, $home, $shell, $a) = split(/:+/, $line); # $a - undef
Функция join берет список значений с склеивает их, ставя между элементами списка строку связку:
$string = join($glue, @list);
$outline = join(":", @fields);

Наши партнёры:
Каталог продукции ООО ВС Подшипник. Информация и прайс.
Советы и примеры - ремонтируем самостоятельно
Для вас Кулинарная книга, рецепты на каждый день.
Дамский уголок - внешность, здоровье, советы и консультации.


Copyright © ClericICN, 2002 - 2009