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

3.12. Внутренние подвыражения

Для указания подвыражений применяется нотация ?>:

re = /(?>abc)(?>def)/   # То же, что /abcdef/

re.match("abcdef").to_a # ["abcdef"]

Отметим, что наличие подвыражения еще не означает группировки. С помощью дополнительных скобок их, конечно, можно превратить в запоминаемые группы.

Еще обратим внимание на то, что эта конструкция собственническая, то есть жадная и при этом не допускает возврата в подвыражение.

str = "abccccdef"

re1 = /(abc*)cdef/

re2 = /(?>abc*)cdef/

re1 =~ str          # 0

re2 =~ str          # nil

re1.match(str).to_a # ["abccccdef", "abccc"]

re2.match(str).to_a # []

В предыдущем примере подвыражение abc* выражения re2 поглощает все вхождения буквы с и (в соответствии с собственническим инстинктом) не отдает их назад, препятствуя возврату.

3.13. Ruby и Oniguruma

Новая библиотека регулярных выражений в Ruby называется Oniguruma. Это японское слово означает что-то вроде «колесо духов». (Те, кто не владеет японским, часто пишут его неправильно; имейте в виду, что тут не обойтись без «guru»!)

Новая библиотека превосходит старую в нескольких отношениях. Прежде всего, она лучше работает с иноязычными строками, а также добавляет кое-какие интересные возможности к регулярным выражениям. Наконец, лицензия на ее использование мягче, чем на использование Ruby в целом. Когда писалась эта книга, Oniguruma еще не была полностью интегрирована в Ruby.

В следующем разделе мы расскажем, как определить, присутствует ли библиотека Oniguruma. А затем покажем, как можно ее собрать, если она не включена в дистрибутив.

3.13.1. Проверка наличия Oniguruma

Если вас интересует библиотека Oniguruma, то первым делом нужно выяснить, есть ли она в вашем экземпляре Ruby. В версиях 1.8.4 и младше ее, скорее всего, нет. Стандартно она включается в дистрибутив версии 1.9.

Вот как можно без труда выяснить, присутствует ли Oniguruma, проверив три условия. Во-первых, как я сказал, она стандартно поставляется в версии 1.9 и старше. В последних версиях обеих библиотек для работы с регулярными выражениями определена строковая константа Regexp::ENGINE. Если она содержит подстроку Oniguruma, то у вас новая библиотека. И последний шаг: если вы все еще не знаете, с какой библиотекой работаете, можно попытаться вычислить регулярное выражение, записанное в «новом» синтаксисе. Если при этом возникнет исключение SyntaxError, значит, у вас старая библиотека; в противном случае — новая.

def oniguruma?

 return true if RUBY_VERSION >= "1.9.0"

 if defined?(Regexp::ENGINE) # Константа ENGINE определена?

  if Regexp::ENGINE.include?('Oniguruma')

   return true               # Какая-то версия Oniguruma.

  else

   return false              # Старая библиотека,

  end

 end

 eval("/(?<!a)b/")           # Новый синтаксис.

  return true                # Сработало: новая библиотека.

 rescue SyntaxError          # Не сработало: старая библиотека.

  return false

 end

puts oniguruma?

3.13.2. Сборка Oniguruma

Если в вашу версию библиотека Oniguruma не включена, можете самостоятельно откомпилировать Ruby и скомпоновать с недостающей библиотекой. Ниже приведены соответствующие инструкции. Эта процедура должна работать начиная с версии 1.6.8 (хотя она уже совсем старенькая).

Получить исходный текст Oniguruma можно из архива приложений Ruby RAA (http://raa.ruby-lang.org/) или найти в другом месте. Исходные тексты Ruby, естественно, находятся на официальном сайте.

Если вы работаете на платформе UNIX (в том числе в среде Cygwin в Windows или Mac OS/X), выполните следующие действия:

1. gunzip oniguruma.tar.gz

2. tar xvf oniguruma.tar

3. cd oniguruma

4. ./configure with-rubydir=<ruby-source-dir>

5. Одно из следующих:

make 16 # Для Ruby 1.6.8

make 18 # Для Ruby 1.8.0/1.8.1

6. cd ruby-source-dir

7. ./configure

8. make clean

9. make

10. make test # Простой тест интерпретатора Ruby.

11. cd ../oniguruma # Укажите путь к библиотеке.

12. make rtest

Или:

make rtest RUBYDIR=ruby-install-dir

Если же вы работаете на платформе Win32, скажем в Windows XP, то потребуются Visual C++ и исполняемый файл patch.exe. Выполните следующие действия:

1. Распакуйте архив любой имеющейся у вас программой.

2. copy win32\Makefile Makefile

3. Одно из следующих:

nmake 16 RUBYDIR=ruby-source-dir # для Ruby 1.6.8

nmake 18 RUBYDIR=ruby-source-dir # для Ruby 1.8.0/1.8.1

4. Следуйте инструкции в файле ruby-source-dir\win32\README.win32.

При возникновении ошибок обратитесь в список рассылки или конференцию.

3.13.3. Некоторые новые возможности Oniguruma

Oniguruma добавляет много новых возможностей к механизму работы с регулярными выражениями в Ruby. Из самых простых отметим дополнительную управляющую последовательность для указания класса символов. Если \d и \D соответствуют десятичным цифрам и не цифрам, то \h и \H являются аналогами для шестнадцатеричных цифр:

"abc" =~ /\h+/ #0

"DEF" =~ /\h+/ # 0

"abc" =~ /\Н+/ # nil

Добавилось возможностей у классов символов в квадратных скобках. Для организации вложенных классов можно применять оператор &&. Вот как можно записать регулярное выражение, соответствующее любой букве, кроме гласных а, е, i, о, u:

reg1 = /[a-z&&[^aeiou]]/ # Задает пересечение.

А следующее выражение соответствует всему алфавиту, кроме букв от m до p:

reg2 = /[a-z&&[^m-р]]/

Поскольку такие выражения выглядят не очень понятно, рекомендую пользоваться этим средством осмотрительно.

Другие возможности Oniguruma, например оглядывание назад и именованные соответствия, будут рассмотрены ниже. Все связанное с интернационализацией отложим до главы 4.