Выбрать главу

class String

 def detab(ts=8)

  str = self.dup

  while (leftmost = str.index("\t")) != nil

   space = " "* (ts-(leftmost%ts))

   str[leftmost]=space

  end

  str

 end

 def entab(ts=8)

  str = self.detab

  areas = str.length/ts

  newstr = ""

  for a in 0..areas

   temp = str[a*ts..a*ts+ts-1]

   if temp.size==ts

    if temp =~ /+/

     match=Regexp.last_match[0]

     endmatch = Regexp.new(match+"$")

     if match.length>1

      temp.sub!(endmatch,"\t")

     end

    end

   end

   newstr += temp

  end

  newstr

 end

end

foo = "Это всего лишь тест. "

puts foo

puts foo.entab(4)

puts foo.entab(4).dump

Отметим, что этот код не распознает символы забоя.

2.40. Цитирование текста

Иногда бывает необходимо напечатать длинные строки текста, задав ширину поля. Приведенный ниже код решает эту задачу, разбивая текст по границам слов и учитывая символы табуляции (но символы забоя не учитываются, а табуляция не сохраняется):

str = <<-EOF

  When in the Course of human events it becomes necessary

  for one people to dissolve the political bands which have

  connected them with another, and to assume among the powers

  of the earth the separate and equal station to which the Laws

  of Nature and of Nature's God entitle them, a decent respect

  for the opinions of mankind requires that they should declare the

  causes which impel them to the separation.

EOF

max = 20

line = 0

out = [""]

input = str.gsub(/\n/, " ")

words = input.split(" ")

while input ! = ""

 word = words.shift

 break if not word

 if out[line].length + word.length > max

  out[line].squeeze!(" ")

  line += 1

  out[line] = ""

 end

 out[line] << word + " "

end

out.each {|line| puts line} # Печатает 24 очень коротких строки.

Библиотека Format решает как эту, так и много других схожих задач. Поищите ее в сети.

2.41. Заключение

Мы обсудили основы представления строк (заключенных в одиночные или двойные кавычки). Поговорили о том, как интерполировать выражения в строку в двойных кавычках; узнали, что в таких строках допустимы некоторые специальные символы, представленные управляющими последовательностями. Кроме того, мы познакомились с конструкциями %q и %Q, которые позволяют нам по своему вкусу выбирать ограничители. Наконец, рассмотрели синтаксис встроенных документов, унаследованных из старых продуктов, в том числе командных интерпретаторов в UNIX.

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

Пришло время перейти к тесно связанной со строками теме — регулярным выражениям. Регулярные выражения — это мощное средства сопоставления строк с образцами. Мы рассмотрим их в следующей главе.

Глава 3. Регулярные выражения

Я провела бы его по лабиринту, где тропы орнаментом украшены…

Эми Лоуэлл

Мощь регулярных выражений как инструмента программирования часто недооценивается. Первые теоретические исследования на эту тему датируются сороковыми годами прошлого века, в вычислительные системы они проникли в 1960-х годах, а затем были включены в различные инструментальные средства операционной системы UNIX. В 1990-х годах популярность языка Perl привела к тому, что регулярные выражения вошли в обиход, перестав быть уделом бородатых гуру

Красота регулярных выражений заключается в том, что почти весь наш опыт можно выразить в терминах образцов. А если имеется образец, то можно провести сопоставление с ним, можно найти то, что ему соответствует, и заменить найденное чем-то другим по своему выбору.

Во время работы над данной книгой язык Ruby находился в переходном состоянии. Старая библиотека регулярных выражений заменялась новой под названием Oniguruma. Этой библиотеке посвящен раздел 3.13 данной главы. Что касается интернационализации, то это тема главы 4.

3.1. Синтаксис регулярных выражений

Обычно регулярное выражение ограничено с двух сторон символами косой черты. Применяется также форма %r. В таблице 3.1 приведены примеры простых регулярных выражений:

Таблица 3.1. Простые регулярные выражения

Регулярное выражение Пояснение /Ruby/ Соответствует одному слову Ruby /[Rr]uby/ Соответствует Ruby или ruby /^abc/ Соответствует abc в начале строки %r(xyz$) Соответствует xyz в конце строки %r|[0-9]*| Соответствует любой последовательности из нуля или более цифр

Сразу после регулярного выражения можно поместить однобуквенный модификатор. В таблице 3.2 приведены наиболее часто употребляемые модификаторы.