Анимация
JavaScript


Главная  Библионтека 

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [ 38 ] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

Как и в операции сопоставления, можно выбрать другой разделитель, если косая черта неудобна. Для этого просто нужно использовать один символ три раза*;

s#fred#barney#; # заменить fred на barney, как в s/fred/barney/

Как и при сопоставлении, можно с помощью операции =~ указать другой объект для проведения замены. В этом случае объект должен быть таким, которому можно присвоить скалярное значение, - например, скалярной переменной или элементом массива;

$which = "this is а test";

Swhich =~ s/test/quiz/; # $which теперь содержит "this is a quiz"

Ssomeplace[Shere] =~ s/left/right/; # заменить элемент массива

Sd{"t") =~ s/-/x /; # поставить "x " перед элементом массива

Функции split и join

Регулярные выражения можно использовать для разбивки строки на поля. Это делает функция split. Функция join выполняет противоположное действие - вновь "склеивает" эти кусочки.

Функция split

Функция spilt получает регулярное выражение и строку и ищет в этой строке все экземпляры указанного регулярного выражения. Те части строки, которые не совпадают с регулярным выражением, возвращаются по порядку как список значений. Вот, например, код синтаксического анализа разделенных двоеточиями полей, аналогичных тем, которые используются в UNIX-файлах /etc/passwd:

$line = "merlyn::118:10:Randal:/home/merlyn:/usr/bin/perl"; @fields = split (/:/, Sline) ; # разбить Slme, используя в качестве

# разделителя двоеточие

# теперь gfields содержит ("тег1уп","", "118", "10",

# "Randal" , "/home/merlyn", "/usr/bm/perl" )

Обратите внимание на то, что второе пустое поле стало пустой строкой. Если вы этого не хотите, задайте сопоставление следующим образом;

efields = split(/:+/, $line);

Здесь при сопоставлении принимаются во внимание одно и более расположенных рядом двоеточий, поэтому пустое поле не образуется.

Очень часто приходится разбивать на поля значение переменной $ , поэтому этот случай предлагается по умолчанию;

S = "some string";

@words = split (/ /); # TO же самое, что и @words = split (/ /, $ ) ;

* Или две пары, если используется символ из пары "левая-правая".



При такой разбивке соседние пробелы в разбиваемой строке вызовут появление пустых полей (пустых строк). Лучше использовать образец / +/, а лучше /\з+/, который соответствует одному и более пробельным символам. Этот образец, по сути дела, используется по умолчанию*, поэтому, если вы разбиваете переменную $ по пробельным символам, вы можете использовать все стандартные значения и просто написать :

@words = split; # то же самое, что и @words = split(/\s+/, $ ) ;

Завершающие строки пустые поля в список, как правило, не включаются. Особой роли это обычно не играет. Решение вроде

$line = "merlyn::118:10:Randal:/home/merlyn:";

(5nanie, $password, $uid, $gid, $gcos, $home, $shell) = split (1:1, $line);

# разбить $line, используя в качестве разделителя двоеточие

просто присваивает переменной $ she 11 нулевое значение (undef), если эта строка недостаточно длинна или содержит в последнем поле пустые значения. (Разбиение выполняется так, что лишние поля просто игнорируются.)

Функция Join

Функция join берет список значений и "склеивает" их, ставя между элементами списка строку-связку. Выглядит это так:

$bigstring = ]oin($glue,@list);

Например, чтобы восстановить строку пароля, попробуйте использовать следующее:

$outline = ]oin(":", @fields);

Отметим, что строка-связка - это не регулярное выражение, а обычная строка, состоящая из символов общим числом нуль или более.

Если нужно поставить связку не между элементами, а перед каждым элементом, то достаточно такого трюка;

$result = (]oin " + ", @fields);

Здесь пустая строка "" рассматривается как пустой элемент, который должен быть связан с первым элементом данных массива @fields.B результате связка помещается перед каждым элементом. Аналогичным образом можно поставить пустой элемент-связку в конец списка:

$output = ]01п ("\п", @data, "");

* На самом деле образец по умолчанию - строка "", поэтому начальный пробельный разделитель игнорируется, но для нас вышесказанного пока достаточно



Упражнения

Ответы к упражнениям даны в приложении А.

1. Постройте регулярное выражение, которое соответствует:

а) минимум одному символу а, за которым следует любое число символов Ь;

б) любому числу обратных косых, за которым следует любое число звездочек (любое число может быть и нулем);

в) трем стоящим подряд копиям того, что содержится в переменной

$whatever;

г) любым пяти символам, включая символ новой строки;

д) одному слову, написанному два или более раз подряд (с возможно изменяющимся пробельным символом), где "слово" определяется как непустая последовательность непробельных символов.

2. а) Напишите программу, которая принимает список слов из stdin и

ищет строку, содержащую все пять гласных (а, е, i, о и и). Запустите эту программу с /usr/dict/words* и посмотрите, что получится. Другими словами, введите

$ программа </usr/dict/words

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

в) Модифицируйте программу так, чтобы все гласные должны были стоять в порядке возрастания, чтобы все пять гласных должны были присутствовать и чтобы перед буквой "а" не стояла буква "е", перед буквой "е" не стояла буква "i" и т.д.

3. Напишите программу, которая просматривает файл /etc/passwct* (из stdin), выводя на экран регистрационное имя и реальное имя каждого пользователя. (Совет: с помощью функции split разбейте строку на поля, а затем с помощью s / избавьтесь от тех частей поля comment, которые стоят после первой запятой.)

* Словарь вашей системы может находиться не в каталоге /usr/dict/words; обратитесь к man-странице spell(l).

** Если используется NIS, то файл /etc/passwd в вашей системе будет содержать мало данных Посмотрите, может быть, ypcat passwd даст больше информации.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 [ 38 ] 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103