Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Возможно, вы думаете, что неакцентированные символы в некотором смысле эквивалентны своим акцентированным вариантам. Это почти всегда не так. Здесь мы имеем дело с разными символами. Убедимся в этом на примере метода
count$KCODE = "u"sword.count("e") # 1 (не 3)Но для составных (не монолитных) символов верно прямо противоположное. В этом случае латинская буква распознается.
Метод
countjcount$KCODE = "u"sword.count("eé") # 5 (не 3)sword.jcount("eé") # 3Существует вспомогательный метод
mbchar?$KCODE = "u"sword.mbchar? # 0 (смещение первого многобайтового символа)"foo".mbchar? # nilВ библиотеке
jcodechopdeletesqueezesucctrtr_sjcodeМожно побайтно просматривать строку, как обычно, с помощью итератора
each_byteeach_chareach_char$KCODE = "u"sword.each_byte {|x| puts x } # Шесть строк с целыми числами.sword.each_char {|x| puts x } # Четыре строки со строками.Если вы запутались, не переживайте. Все мы через это проходили. Я попытался свести все вышесказанное в таблицу 4.1.
Таблица 4.1. Составные и монолитные формы
| Монолитная форма "é" | ||||
|---|---|---|---|---|
| Название символа | Глиф | Кодовая позиция | Байты UTF-8 | Примечания |
| Строчная латинская e с акутом | é | U+00E9 | 0xC3 0хА9 | Один символ, одна кодовая позиция, один байт |
| Составная форма "é" | ||||
| Название символа | Глиф | Кодовая позиция | Байты 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 endendКонечно, здесь не реализована значительная часть функциональности настоящего метода
[]У метода
unpackU*Ucodepoints = 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.joinendУ метода
String#unpackArray#pack[233, 112, 233, 101].pack('U*') # "épée" Мы можем воспользоваться им, чтобы вставить Unicode-символы, которые трудно ввести с клавиатуры:
eacute = [0хЕ9].pack('U')cafe = "caf#{eacute}" # "café"Регулярным выражениям тоже известно о многобайтовых символах, особенно если вы пользуетесь библиотекой Oniguruma (мы рассматривали ее в главе 3). Например, образец
/./
