Чтение онлайн

на главную - закладки

Жанры

Программирование на языке Ruby
Шрифт:

sword.each_byte {|x| puts x } # Шесть строк с целыми числами.

sword.each_char {|x| puts x } # Четыре строки со строками.

Если вы запутались, не переживайте. Все мы через это проходили. Я попытался свести все вышесказанное в таблицу 4.1.

Таблица 4.1. Составные и монолитные формы

Монолитная форма "'e"
Название символа Глиф Кодовая позиция Байты UTF-8 Примечания
Строчная
латинская e с акутом
'e U+00E9 0xC3 0хА9 Один символ, одна кодовая позиция, один байт
Составная форма "'e"
Название символа Глиф Кодовая позиция Байты UTF-8 Примечания
Строчная латинская е е U+0065 0x65 Один символ, две кодовых позиции (два «программистских символа»), три байта UTF-8
Модифицирующий акут U+0301 0xCC 0x81

Что еще надо учитывать при работе с интернациональными строками? Квадратные скобки по-прежнему относятся к байтам, а не к символам. Но при желании это можно изменить. Ниже приведена одна из возможных реализаций (не особенно эффективная, зато понятная):

class String

 def [](index)

self.scan(/./)[index]

 end

 def []=(index,value)

arr = self.scan(/./)

arr[index] = value

self.replace(arr.join)

value

 end

end

Конечно, здесь не реализована значительная часть функциональности настоящего метода

[]
, который понимает диапазоны, регулярные выражения и т.д. Если вам все это нужно, придется запрограммировать самостоятельно.

У метода

unpack
есть параметры, помогающие манипулировать Unicode-строками. Указав в форматной строке параметр
U*
, мы можем преобразовать строку в кодировке UTF-8 в массив кодовых позиций (
U
без звездочки преобразует только первую кодовую позицию):

codepoints = sword.unpack('U*') # [233, 112, 233, 101]

Вот несколько более полезный пример, в котором все кодовые позиции в строке, отличные от ASCII (то есть начиная с U+0080), преобразуются к виду U+XXXX, который мы обсуждали выше:

def reveal_non_ascii(str)

 str.unpack('U*').map do |cp|

 if cp < 0x80

cp.chr

 else

'(U+%04X)' % cp

 end

 end.join

end

У метода

String#unpack
есть «близкий родственник»
Array#pack
, выполняющий
обратную операцию:

[233, 112, 233, 101].pack('U*') # "'ep'ee"

Мы можем воспользоваться им, чтобы вставить Unicode-символы, которые трудно ввести с клавиатуры:

eacute = [0хЕ9].pack('U')

cafe = "caf#{eacute}" # "caf'e"

Регулярным выражениям тоже известно о многобайтовых символах, особенно если вы пользуетесь библиотекой Oniguruma (мы рассматривали ее в главе 3). Например, образец

/./
сопоставляется с одним многобайтовым символом.

Модификатор

u
извещает регулярное выражение о том, что мы работаем с кодировкой UTF-8. Если
$KCODE
равно
"u"
, то модификатор можно не задавать, однако это и не повредит. (К тому же такая избыточность может быть полезна, если код является частью большой программы, а какое значение переменной
$KCODE
в ней установлено, вам неизвестно.)

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

$KCODE = "u"

sword =~ /\w/ #0

sword =~ /\W/ # nil

При наличии Oniguruma последовательности, начинающиеся с символа обратной косой черты (

\w
,
\s
и т.п.) распознают и более широкие диапазоны кодовых точек: слова, пропуски и т.д.

Регулярные выражения позволяют безопасно выполнять простые манипуляции со строками. Мы и так можем без труда усекать строки. Следующий код возвращает не более 20 символов из строки

ascii_string
:

ascii_string[0,20]

Однако, поскольку кодовая позиция Unicode может занимать более одного байта такую технику нельзя безопасно применять к строке в кодировке UTF-8. Есть риск, что в конце строки окажется недопустимая последовательность байтов. Кроме того, это не слишком полезно, так как мы не можем заранее сказать, сколько в результате получится кодовых позиций. На помощь приходят регулярные выражения:

def truncate(str, max_length)

 str[/.{0,#{max_length}}/m]

end

4.2.3. Распознавание кодировки

Распознать, в какой кодировке записана данная строка, довольно сложно. Многобайтовые кодировки обладают отличительными признаками, по которым их можно опознать, но с однобайтовыми — а именно они применяются в западных языках — дело обстоит куда хуже. Для решения можно применить статистические методы, но эта тема выходит за рамки данной книги (к тому же результат в общем случае получается не слишком надежным).

К счастью, обычно перед нами стоит более простая задача — выяснить, записана ли строка в кодировке UTF-8. На этот вопрос можно дать достаточно надёжный ответ. Приведем один способ (основанный на том, что метод

unpack
возбуждает исключение, если ему передана некорректная строка):

class String

 def utf8?

unpack('U*') rescue return false

true

 end

end

Поделиться:
Популярные книги

Варяжская сталь: Герой. Язычник. Княжья Русь

Мазин Александр Владимирович
Варяг
Фантастика:
боевая фантастика
попаданцы
альтернативная история
8.67
рейтинг книги
Варяжская сталь: Герой. Язычник. Княжья Русь

Газлайтер. Том 14

Володин Григорий Григорьевич
14. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
4.75
рейтинг книги
Газлайтер. Том 14

Управленческая элита. Как мы ее отбираем и готовим

Тарасов Владимир
Деловая литература:
управление, подбор персонала
5.00
рейтинг книги
Управленческая элита. Как мы ее отбираем и готовим

Вероника

Знаменская Алина
Проза:
современная проза
8.77
рейтинг книги
Вероника

Жизнь замечательных Блонди

Измайлова Кира Алиевна
1. Ai no Kusabi
Фантастика:
космическая фантастика
8.29
рейтинг книги
Жизнь замечательных Блонди

Позывной "Князь" 2

Котляров Лев
2. Князь Эгерман
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Позывной Князь 2

Первоистоки Русов

Петухов Юрий Дмитриевич
Научно-образовательная:
история
3.40
рейтинг книги
Первоистоки Русов

Неучтенный элемент. Том 11

NikL
11. Антимаг. Вне системы
Фантастика:
фэнтези
5.00
рейтинг книги
Неучтенный элемент. Том 11

Пришествие Зверя том 2. Антология

Хейли Гай
Warhammer 40000
Фантастика:
боевая фантастика
5.00
рейтинг книги
Пришествие Зверя том 2. Антология

"Фантастика 2025-59". Компиляция. Книги 1-29

Римшайте Кристина Антановна
Фантастика 2025. Компиляция
Фантастика:
фэнтези
боевая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Фантастика 2025-59. Компиляция. Книги 1-29

Горчаков. Пенталогия

Пылаев Валерий
Горчаков
Фантастика:
фэнтези
5.50
рейтинг книги
Горчаков. Пенталогия

Практикантка. Дилогия

Каменистый Артем
Практикантка
Фантастика:
боевая фантастика
9.05
рейтинг книги
Практикантка. Дилогия

Голос ночной птицы

МакКаммон Роберт Рик
1. Мэтью Корбетт
Детективы:
исторические детективы
8.97
рейтинг книги
Голос ночной птицы

Точка Бифуркации VIII

Смит Дейлор
8. ТБ
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Точка Бифуркации VIII