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

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

Жанры

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

str = "ABC"

chars = str.scan(/./)

chars.each {|char| print char, " " }

#Результат: ABC.

2.7. Специализированное сравнение строк

В язык Ruby уже встроен механизм сравнения строк: строки сравниваются в привычном лексикографическом порядке (то есть на основе упорядочения, присущего данному набору символов). Но при желании можно задать собственные правила сравнения любой сложности.

Предположим,

например, что мы хотим игнорировать английские артикли a, an и the, если они встречаются в начале строки, а также не обращать внимания на большинство знаков препинания. Для этого следует переопределить встроенный метод
<=>
(он вызывается из методов
<
,
<=
,
>
и
>=
). В листинге 2.1 показано, как это сделать.

Листинг 2.1. Специализированное сравнение строк

class String

 alias old_compare <=>

 def <=>(other)

a = self.dup

b = other.dup

# Удалить знаки препинания.

a.gsub!(/[\,\.\?\!\:\;]/, "")

b.gsub!(/[\,\.\?\!\:\;]/, "")

# Удалить артикли из начала строки.

a.gsub!(/^(a |an | the )/i, "")

b.gsub!(/^(a |an | the )/i, "")

# Удалить начальные и хвостовые пробелы.

a.strip!

b.strip!

# Вызвать старый метод <=>.

# a.old_compare(b)

 end

end

title1 = "Calling All Cars"

title2 = "The Call of the Wild"

# При стандартном сравнении было бы напечатано "yes".

if title1 < title2

 puts "yes"

else

 puts "no" # А теперь печатается "no".

end

Обратите внимание, что мы «сохранили» старый метод

<=>
с помощью ключевого слова
alias
и в конце вызвали его. Если бы мы вместо этого воспользовались методом
<
, то был бы вызван новый метод
<=>
, что привело бы к бесконечной рекурсии и в конечном счете к аварийному завершению программы.

Отметим также, что оператор

==
не вызывает метод
<=>
(принадлежащий классу-примеси
Comparable
). Это означает, что для специализированной проверки
строк на равенство пришлось бы отдельно переопределить метод
==
. Но в рассмотренном случае в этом нет необходимости.

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

casecmp
; надо лишь добиться, чтобы он вызывался при сравнении. Вот как это можно сделать:

class String

 def <=>(other)

casecmp(other)

 end

end

Есть и более простой способ:

class String

 alias <=> casecmp(other)

end

Но это не все. Надо еще переопределить оператор

==
, чтобы он вел себя точно так же:

class String

 def ==(other)

casecmp(other) == 0

 end

end

Теперь все строки будут сравниваться без учета регистра. И при всех операциях сортировки, которые определены в терминах метода

<=>
, регистр тоже не будет учитываться.

2.8. Разбиение строки на лексемы

Метод

split
разбивает строку на части и возвращает массив лексем. Ему передаются два параметра: разделитель и максимальное число полей (целое).

По умолчанию разделителем является пробел, а точнее, значение специальной переменной

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

s1 = "Была темная грозовая ночь."

words = s1.split # ["Была", "темная", "грозовая", "ночь]

s2 = "яблоки, груши, персики"

list = s2.split(", ") # ["яблоки", "груши", "персики"]

s3 = "львы и тигры и медведи"

zoo = s3.split(/ и /) # ["львы", "тигры", "медведи"]

Второй параметр ограничивает число возвращаемых полей, при этом действуют следующие правила:

1. Если параметр опущен, то пустые поля в конце отбрасываются.

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

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

Ниже приведены примеры:

str = "alpha,beta,gamma,,"

list1 = str.split(",") # ["alpha","beta","gamma"]

list2 = str.split(",",2) # ["alpha", "beta,gamma,,"]

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

Меченный смертью. Том 5

Юрич Валерий
5. Меченный смертью
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Меченный смертью. Том 5

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Морской волк. 1-я Трилогия

Савин Владислав
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Морской волк. 1-я Трилогия

Тайные поручения

Билик Дмитрий Александрович
6. Бедовый
Фантастика:
юмористическое фэнтези
городское фэнтези
мистика
5.00
рейтинг книги
Тайные поручения

Бояръ-Аниме. Газлайтер. Том 30

Володин Григорий Григорьевич
30. История Телепата
Фантастика:
альтернативная история
аниме
фэнтези
5.00
рейтинг книги
Бояръ-Аниме. Газлайтер. Том 30

Последний Паладин. Том 2

Саваровский Роман
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Последний Паладин. Том 2

Темный Лекарь 2

Токсик Саша
2. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 2

#Бояръ-Аниме. Газлайтер. Том 11

Володин Григорий Григорьевич
11. История Телепата
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
#Бояръ-Аниме. Газлайтер. Том 11

Законы Рода. Том 2

Андрей Мельник
2. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Законы Рода. Том 2

Защитник

Кораблев Родион
11. Другая сторона
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Защитник

Княжна попаданка. Последняя из рода

Семина Дия
1. Княжна попаданка. Магическая управа
Фантастика:
попаданцы
альтернативная история
историческое фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Княжна попаданка. Последняя из рода

Последний Паладин. Том 12

Саваровский Роман
12. Путь Паладина
Фантастика:
аниме
фэнтези
попаданцы
5.00
рейтинг книги
Последний Паладин. Том 12

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

Винокуров Юрий
17. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга XVII

Великий род

Сай Ярослав
3. Медорфенов
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Великий род