Программирование на perl — использование метасимволов и запоминания
Пример 2
$_="1+2-3*4";
/(d)(?!+)/
Найти цифру, за которой нет знака +. В этом случае тоже будет 2.
4. (?<=шаблон) — заглядывание назад. Требует, чтобы перед текущей точкой находился соответствующий текст. Так шаблон /(?<=s)w+/лон ищет слово, перед которым имеется пробельный символ. В отличии от заглядывания вперед заглядывание назад может работать только с фиксированным числом проверяемых символов.
5. (?<!шаблон) — заглядывание назад по отрицанию. Перед текщей точкой не должно быть текста, соотносимогос заданным шаблоном. Соответственно, от команды /(?<!s)w+/лон требуется найти слово, перед которым нет пробельного символа.
Операции замены
РВ работают не только для поиска, но и для замены.
1. Простейшая форма
S/PB/новая_строка/
В данном случае $_ сопоставляется с РВ. Если оно успешно, то соответстыуящая часть строки отбрасывается и заменяется строкой "новая_строка". Если сопоставление неудачно, то ничего не происходит.
2. Замена при всех совпадениях
Чтобы замена происходила при всех совпадениях в строке, в РВ надо добавить опцию g (глобальная замена).
$_="foot fool buffoon";
S/foo/bar/g
Теперь в $_ будет: "bart barl bufbarn".
3. Интерполяция при замене
В заменяющей строке производится интерполяция переменных, что позволяет задавать эту строку во время выполнения.
$_="hello, world";
$new="goodbye";
S/hello/$new/;
Что даст $_="goodbye, world".
4. Использование метасимволов и запоминания
$_="This is a test";
S/(w+)/<$1>/g
Здесь:
— w+ — любое слово;
— (w+) – оно запоминается в 1 и $1;
— получаем слово в угловых скобках;
— g – глобальная замена.
В результате переменная $_ будет иметь вид:
"<This> <is> <a> <test>"
5. Применение опции i
Заставляет в РВ игнорировать регистр. Может стоять после g или перед g.
6. Другой разделитель
Как и при сопоставлении можно использовать другой разделитель. Для этого надо использовать один символ три раза (т. е. без операции m).
S#fred#barney#;
Что эквивалентно S/fred/barney/
7. Иные объекты для замены — =~
Операция =~ позволяет указать другой объект для замены, а не $_.
Внимание!
Объект должен быть таким, чтобы ему можно присвоить скалярное значение.
Пример:
$sw="This is a test";
$sw=~s/test/quiz/; # Теперь переменная $sw имеет вид
# "This is a quiz " ("Это шутка")
$arr[$here]=~s/left/right; # Замена элемента массива
$d{"t"}=~s/^/x /; # В хеше поставить "х " перед
#элементом в начале строки
Другие опции:
m – считать строку многострочной;
s – считать строку однострочной;
x – расширенный синтаксис (использование пробелов и
комментариев);
e – правя часть s/// представляет выполнимый код;
ee – правая чпсть выполняется, после чего возвращаемое значение интерпретируется снова.
Функции, используемые в РВ
1. Функция split
Предназначена для разбивки строки на поля (элементы). Она получает РВ и строку, и ищет в этой строке все экземпляры указанного РВ. Те части строки, что не совпадают с РВ, возвращаются по порядку как список значений.
Пример: Разбить строку $line, используя в качестве разделителя двоеточие.
$line="merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl";
@fields = split(/:/, $line);
Массив @fields содержит 7 элементов:
"merlyn", "" ,"118","10","Randal","/home/merlyn","/usr/bin/perl".
В левой части вместо переменной массива может быть просто список переменных ($a1,$a2,$a3 и так далее). Если этот список длиннее, чем количество полей, то последние переменные будут не определены.
Если этот список короче, чем количество полей, то в него будут занесены первые значения.
У нас второй элемент стал пустой строкой. Если этого не надо, то РВ можно задать так:
@fields=split(/:+/,$line);
Здесь во внимание будет приниматься одно и более двоеточий, поэтому пустое поле не будет образовываться.
Для разбивки строка в $_ используется по умолчанию
$_="some string";
@words=split(/ /);
Что эквивалентно @words=split(/ /,$_);
Здесь, чтобы соседние пробелы не делали пустых полей, надо использовать / +/, а лучше /s+/. Здесь s соответствует одному или более пробельным символам. Это по умолчанию.
Если вы хотите разбить $_ по пробельным символам, то достаточно применить упрощенную запись:
@words=split;
Это эквивалентно:
@words=split(/s+/,$_);
2. Функция join
Берет список значений и "склеивает" в одну строку, ставя между элементами списка строку-связку. Строка-связка – это не РВ, а обыкновенная строка.
$line=join(строка-связка, список значений);
Пример:
$outline=join(":",@fields);
Для того, чтобы поставить связку перед каждым элементом, а не
только между элементами, надо:
$res=join("+","",@fields);
Здесь пустая строка "" рассматривается как пустой элемент, который должен быть связан с первым элементом массива @fields, то есть мы как бы перед первым элементом массива @fields поставили еще один элемент, который является пустой строкой. Тогда связка будет стоять перед каждым элементом. Аналогично, можно поставить пустой элемент-связку в конец списка.
Пример:
$output=join("n",@data,"");
Здесь после каждого элемента и после последнего будут стоять признаки новой строки.
Другие операции работы со строкой
Поиск подстроки
1. Операция index
$x=index($str,$subst);
Ищется первое вхождение subst в строке str и возвращается целочисленный индекс первого символа. Если вхождений нет, то возвращается –1.
str и subst могут быть:
— литеральной строкой;
— скалярной переменной, содержащей строку;
— выражение, которое имеет строковое значение;
Для определения следующих вхождений используется третий параметр – минимальный индекс, с которого ищется вхождение
$x=index($str,$subst, k);
2. Операция rindex
Просмотр справа налево. Отыскивается первое вхождение справа. Но возвращается индекс найденной подстроки, отсчитанный слева. 3-й параметр – максимальный индекс, с которого ищется новое вхождение.
3. Функция substr
Для извлечения, если фрагмент находится на известной позиции.
$a=substr($строка,$начало,$длина);
$начало – индекс, с которого начинается извлечение.
$длина – количество извлекаемых символов.
Если $длина равна нулю, то возврат – пустая строка.
Если $длина больше, чем оставшееся количество в строке, то извлекутся только те символы, что есть.
Если $начало меньше нуля, то отсчет, начиная с конца строки. Например, если $начало= -1 и $длина=1, то возвращается один последний символ. А если $начало= -2 и $длина=2, то последние два символа.
Если $начало – большое число положительное число, то всегда возвращается пустая строка.
Если $начало – большое число отрицательное число, то отсчет идет
с нулевой позиции.
Большое число – это значит "Больше длины строки". Последние два свойства пока не работают в Perl 5 под Windows.
Если 1-й параметр — скалярная переменная, то функция substr может находиться в левой части присваивания. Тогда изменится та часть строки, которая была найдена. В этом случае изменится та часть строки, которая была бы возвращена, если бы функция substr использовалась в првой части оператора.
Пример:
$hw="hello world!";
substr($hw,0,5)="bye";
Тогда
$hw="bye world!";
Если длина заменяющего текста больше длины заменяемого текста, то произойдет увеличение длины строки.
Транслитерация — tr
Эта операция позволяет произвести взаимную замену. Например, все буквы a заменит на b, а буквы b заменить на а. Для этого – операция tr:
tr /old_str/new_str/;
Аргументы old_str и new_str обозначают то же самое, что аргументы в операции замены s/ / /. Операция tr меняет содержимое переменной $_,
То есть отыскивает в $_ символы старой строки и заменяет найденные символы соответствующими символами новой строки.
Примеры:
$_="fred and barney";
tr /fb/bf; => $_="bred and farney"
tr /abcde/ABCDE/; => $_="BrED AnD fArnEy"
tr /a-z/A-z/; => $_="BRED AND FARNEY"
Если новая строка короче старой, то последний символ new_str повторяется до тех пор, пока длины не сравняются.
$_="fred";
tr /a-z/x/; => $_="xxxx";
А. Чтобы этого не происходило, то в конце надо поставить опцию d (delete). Тогда последний символ не повторяется.
$_="fred and barney";
tr /a-z/ABCDE/d; => $_="ED AD BAE"
Если новый список пуст и не используется опция d, то новый список тождественен старому списку. Причем возвратом будет количество совпавших символов в старой строке.