Изучаем Perl

       

Транслитерация


Если вам необходимо взять строку и заменить все зкземпляры какого-нибудь символа другим символом или удалить их, зто можно сделать, как вы уже знаєте, с помощью тщательно подобранных команд s///. Предположим, однако, вам нужно превратить все буквы а в буквы Ь, а все буквы b — в буквы а. Зто нельзя сделать посредством двух команд s///, потому что вторая команда отменит все изменения, сделанные первой.

Такое преобразование данных очень просто выполняется в shell с помощью стандартной команды tr(l):

tr ab ba <indata >outdata

(Если вы ничего не знаєте о командо tr, загляните на man-страницу tr(l);

зто полезный инструмент.) В Perl тоже применяется операция tr, которая работает в основном так же:

tr/ab/ba;

Операция tr принимает два аргумента: старая_строка и новая_строка. Они используются так же, как аргументы команды s///; другими словами, имеется некий разделитель, который стоит сразу же за ключевым словом tr и разделяет и завершает аргументы (в данном случае зто косая черта, но в зтой роли могут виступать почти все символы).

Аргументи операции tr похожи на аргументи команды tr(l). Операция tr изменяет содержимое переменной $_ (совсем как si/I}, отыскивая в ней символы старой строки и заменяя найденные символы соответствующи-ми символами новой строки. Вот несколько примеров:

$_ = "fred and barney";

tr/fb/bf; # $ теперь содержит "bred and farney" tr/abcde/ABCDE/; t $_ теперь содержит "BrED AnD fArnEy" tr/a-z/A-Z/; # $_ теперь содержит "BRED AND FARNEY"

Обратите внимание на то, что диапазон символов можно обозначить двумя символами, разделенными дефисом. Если вам нужен в строке дефис как таковой, поставьте перед ним обратную косую.

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

$_ = "fred and barney";



tr/a-z/x/; # $_ теперь содержит "хххх xxx xxxxxx"

Чтобы такое не происходило, поставьте в конце операции tr/// букву d, которая означает delete ("удалить"). В данном случае последний символ не повторяется. Все символы старой строки, для которых нет соответствую-щих символов в новой строке, просто удаляются:


$ = "fred and barney";

tr/a-z/ABCDE/d; # $_ теперь содержит "ED AD BAE"

Обратите внимание на то, что все буквы, стоящие после буквы е, исчезают, потому что в новом списке соответствующей буквы нет, и на то, что на пробелы зто не влияет, потому что их нет в старом списке. По принципу работы зто зквивалентно команде tr c опцией -d.

Если новый список пуст и опция d не используется, то новый список будет совпадать со старым. Зто может показаться глупым — зачем заменять І на І и 2 на 2? — но на самом деле в зтом єсть довольно глубокий смысл. Операция tr/// возвращает количество символов, совпавших со старой строкой, и путем замены символов на самих себя вы можете получить число таких символов, содержащихся в новой строке*. Например:

* Зто справедливо только для одиночних символов. Для подсчета строк в операции сопоставления с образцом используйте флаг /д:

while (/образец/д) { $count++;

>

$_ = "fred and barney";

$count = tr/a-z//; # $_ не изменилась, но $count = 13 $count2 = tr/a-z/A-Z/; # $_ переведена в верхний регистр, и $count2 = 13

Если в конце операции добавить букву с (как мы добавляли букву d), символы старой строки будут рассматриваться как исключение из набора всех 256 символов. Каждый символ, указаними в старой строке, удаляется из совокупности всех возможных символов; оставшиеся символы, взятые по порядку от младшего к старшему, образуют новую строку-результат. Напри-мер, подсчитать или изменить в нашей строке все символы, не являющиеся буквами, можно так:

$_ = "fred and barney";

$count == tr/a-z//c; # $_ не изменилась, но $count = 2

tr/a-z/_/c; # $_ теперь содержит "fred_and_barney" (символы-небуквы => _)

tr/a-z//cd; t $_ теперь содержит "fredandbarney" (символы-небуквы

удалены)

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



Последняя опция операции tr/// — s, которая заменяет множество зкземпляров одной преобразованной буквы одним. Например:

$_ = "aaabbbcccdefghi";

tr/defghi/abcddd/s; # $_ теперь содержит "aaabbbcccabcd"

Обратите внимание: буквы def заменены на abc, a ghi (которые без опции s превратились би в ddd) стали одной буквой d. Отметим также, что стоящие друг за другом буквы в первой части строки "не сжимаются", потому что для них не задано преобразование. Вот еще несколько примеров:

$_ = "fred and barney, wilma and betty";

tr/a-z/X/s; ” $_ теперь содержит "X X X, X X X" $_ = "fred and barney, wilma and betty";

tr/a-z/_/cs; # $_ теперь содержит "fred_and_barney_wilma and betty"

В первом из зтих примеров каждое слово (стоящие друг за другом буквы) было заменено одной буквой х. Во втором примере все группы стоящихдруг за другом символов-небукв стали одиночними знаками подчеркивания.

Как и команда s///, операция tr может бьггь проведена над другой строкой, а не только над строкой, хранящейся в переменной $_. Зто достигается с помощью операции =~:

$names = "fred and barney";

$names =~ tr/aeiou/X/; # $names теперь содержит "frXd Xnd bXrnXy"


Содержание раздела