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

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

Жанры

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

$KCODE = "n"

# Для справки: французское слово "'ep'ee"

# обозначает разновидность меча (sword).

eacute = ""

eacute << 0303 << 0251 # U+00E9

sword = eacute + "p" + eacute + "e"

p eacute # "\303\251"

p sword # "\303\251p\303\251e"

$KCODE = "u"

p eacute # "'e"

p sword # "'ep'ee"

Регулярные выражения в режиме UTF-8 тоже становятся несколько «умнее».

$KCODE = "n"

letters = sword.scan(/(.)/)

# [["\303"], ["\251"], ["p"], ["\303"], ["\251"], ["e"]]

puts letters.size # 6

$KCODE = "u"

letters = sword.scan(/(.)/)

# [["'e"], ["p"], ["'e"], ["e"]]

puts letters.size # 4

Библиотека

jcode
предоставляет также несколько полезных методов, например
jlength
и
each_char
. Рекомендую включать эту библиотеку с помощью директивы
require
всякий раз, как вы работаете с кодировкой UTF-8.

В следующем разделе мы снова рассмотрим некоторые типичные операции со строками и регулярными выражениями. Заодно поближе познакомимся с

jcode
.

4.2.2. Возвращаясь к строкам и регулярным выражениям

При работе с UTF-8 некоторые операции ничем не отличаются. Например, конкатенация строк выполняется так же, как и раньше:

"'eр" + "'eе" # "'ep'ee"

"'eр" << "'eе" # "'ep'ee"

Поскольку UTF-8 не имеет состояния, то для проверки вхождения подстроки тоже ничего специально делать не нужно:

"'ep'ee".include?("'e") # true

Однако при написании интернациональной программы некоторые типичные допущения все же придется переосмыслить. Ясно, что символ больше не эквивалентен байту. При подсчете символов или байтов надо думать о том, что именно мы хотим сосчитать и для чего. То же относится к числу итераций.

По общепринятому соглашению, кодовую позицию часто представляют себе как «программистский символ». Это еще одна полуправда, но иногда она оказывается полезной.

Метод

jlength
возвращает число кодовых позиций в строке, а не байтов. Если нужно получить число байтов, пользуйтесь методом
length
.

$KCODE = "u"

require 'jcode'

sword = "'ep'ee"

sword.jlength # 4

sword.length # 6

Такие методы, как

upcase
и
capitalize
, обычно неправильно работают со специальными символами. Это ограничение текущей версии Ruby. (Не стоит считать ошибкой, поскольку получить представление слова с первой прописной буквой довольно трудно; такая задача просто не решается в схеме интернационализации Ruby. Считайте, что это нереализованное поведение.)

$KCODE = "u"

sword.upcase # "'EP'EE"

sword.capitalize # "'ep'ee"

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

Возможно, вы думаете, что неакцентированные символы в некотором смысле эквивалентны своим акцентированным вариантам. Это почти всегда не так. Здесь мы имеем дело с разными символами. Убедимся в этом на примере метода

count
:

$KCODE = "u"

sword.count("e") # 1 (не 3)

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

Метод

count
возвращает сбивающий с толку результат, когда ему передается многобайтовый символ. Метод
jcount
ведет себя в этом случае правильно:

$KCODE = "u"

sword.count("e'e") # 5 (не 3)

sword.jcount("e'e") # 3

Существует вспомогательный метод

mbchar?
, который определяет, есть ли в строке многобайтовые символы.

$KCODE = "u"

sword.mbchar? # 0 (смещение первого многобайтового символа)

"foo".mbchar? # nil

В библиотеке

jcode
переопределены также методы
chop
,
delete
,
squeeze
,
succ
,
tr
и
tr_s
. Применяя их в режиме UTF-8, помните, что вы работаете с версиями, «знающими о многобайтовости». При попытке манипулировать многобайтовыми строками без библиотеки
jcode
вы можете получить странные или ошибочные результаты.

Можно побайтно просматривать строку, как обычно, с помощью итератора

each_byte
. А можно просматривать посимвольно с помощью итератора
each_char
. Второй способ имеет дело с односимвольными строками, первый (в текущей версии Ruby) — с однобайтными целыми. Разумеется, мы в очередной раз приравниваем кодовую позицию к символу. Несмотря на название, метод
each_char
на самом деле перебирает кодовые позиции, а не символы.

$KCODE = "u"

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

Барон ломает правила

Ренгач Евгений
11. Закон сильного
Фантастика:
аниме
фэнтези
фантастика: прочее
попаданцы
5.00
рейтинг книги
Барон ломает правила

Жертва

Привалов Сергей
2. Звездный Бродяга
Фантастика:
боевая фантастика
космическая фантастика
рпг
попаданцы
6.25
рейтинг книги
Жертва

Обреченная

Макдевит Джек
2. Космоархеологи
Фантастика:
научная фантастика
7.00
рейтинг книги
Обреченная

Далекие горизонты (сборник)

Ле Гуин Урсула Кребер
Фантастика:
фэнтези
научная фантастика
космическая фантастика
5.00
рейтинг книги
Далекие горизонты (сборник)

Мастер големов

Назимов Константин Геннадьевич
4. Травник
Фантастика:
фэнтези
5.25
рейтинг книги
Мастер големов

Стеллар. Компиляция. Книги 1-9

Прокофьев Роман Юрьевич
Стеллар
Фантастика:
киберпанк
рпг
постапокалипсис
технофэнтези
5.00
рейтинг книги
Стеллар. Компиляция. Книги 1-9

Снежная королева

Виндж Джоан
1. Снежная королева
Фантастика:
научная фантастика
8.50
рейтинг книги
Снежная королева

Киберпространство

Ливадный Андрей Львович
43. Экспансия: История Галактики
Фантастика:
космическая фантастика
7.69
рейтинг книги
Киберпространство

Гримуар тёмного лорда I

Грехов Тимофей
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Гримуар тёмного лорда I

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

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

Первый среди равных. Книга XIV

Бор Жорж
14. Первый среди Равных
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Первый среди равных. Книга XIV

Последний реанорец. Том I и Том II

Павлов Вел
1. Высшая Речь
Фантастика:
фэнтези
7.80
рейтинг книги
Последний реанорец. Том I и Том II

Стечкин

Чуев Феликс Иванович
582. Жизнь замечательных людей
Документальная литература:
биографии и мемуары
5.00
рейтинг книги
Стечкин

Кодекс Охотника. Книга XXVI

Винокуров Юрий
26. Кодекс Охотника
Фантастика:
попаданцы
5.00
рейтинг книги
Кодекс Охотника. Книга XXVI