Evgenii Legotckoi
21 июня 2016 г. 11:52

User Guide #05 - Ruby - Регулярные выражения

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

Некоторые символы и комбинации символов имеют специальное значение в этих шаблонах, и включают в себя:

[] - определение диапазона (например, [a-z] означает буквы в диапазоне от a до z
\w - буква или цифра, аналогично [0-9A-Za-z]
\W - не цифра и не буква
\s - символы пустого пространства, такие как [ \t\n\r\f]
\S - не символы пустого пространства
\d - символы цифр, такие как [0-9]
\D - не символы цифр
\b - символ забоя (0x08) (только если в заданном диапазоне)
\b - окончание слова (если только не в заданном диапазоне)
\B - граница слова
* -  ноль и большее количество повторений предыдущего шаблона
+ - одно или большее количество повторений предыдущего шаблона
{m,m} - по крайней мере m и не более повторений предыдущего
? - по крайней мере одно повторение предыдущего
| - либо предыдущее, либо последующее выражение может соответствовать
() - группировка


Общим термином для таких шаблонов является Регулярные выражения . В Ruby, как и в Perl, они в основном заключаются в слэши, чем в двойные кавычки. Если Вы никогда не работали с регулярными выражениями до этого, то возможно, имеет смысл потратить некоторое время на знакомство с ними. Они имеют выразительную мощь, которая может спасти вас от головной боли (и множества строчек лишнего кода), если вам понадобится по шаблону сравнивать, искать строки и манипулировать ими.

Например, предположим, что вы хотите проверить, входит ли строка под данное описание: "Начинается с буквы "f" в нижнем регистре, за которой следует одна буква в верхнем регистре, и опционально следует за ней как можно более долгая последовательность символов, пока не встретится буква в нижнем регистре. Если вы являетесь опытным C программистом, то возможно уже написали несколько десятков строк кода в своей голове. Признайтесь в этом; Вы можете себе помочь. Но в Ruby Вам нужно сделать только один запрос к вашей проверяемой строке со следующим регулярным выражением /^f A-Z $/.*

А что думаете о поиске шестнадцатеричного числа, заключённого в треугольные скобки? Без проблем.

  1. ruby> def chab(s) # "contains hex in angle brackets"
  2. | (s =~ /<0(x|X)(\d|[a-f]|[A-F])+>/) != nil
  3. | end
  4. nil
  5. ruby> chab "Not this one."
  6. false
  7. ruby> chab "Maybe this? {0x35}" # wrong kind of brackets
  8. false
  9. ruby> chab "Or this? <0x38z7e>" # bogus hex digit
  10. false
  11. ruby> chab "Okay, this: <0xfc0004>."
  12. true

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

Вот небольшая программа, которая поможет Вам поэкспериментировать с регулярными выражениями. Сохраните её в файл regx.rb и запустите в командной строке " ruby regx.rb"

  1. # Requires an ANSI terminal!
  2.  
  3. st = "\033[7m"
  4. en = "\033[m"
  5.  
  6. while TRUE
  7. print "str> "
  8. STDOUT.flush
  9. str = gets
  10. break if not str
  11. str.chop!
  12. print "pat> "
  13. STDOUT.flush
  14. re = gets
  15. break if not re
  16. re.chop!
  17. str.gsub! re, "#{st}\\&#{en}"
  18. print str, "\n"
  19. end
  20. print "\n"

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

  1. str> foobar
  2. pat> ^fo+
  3. foobar
  4. ~~~

Совпадающая часть помечена в листинге следующей линией "~~~".

Давайте попробуем ещё больше вводов.

  1. str> abc012dbcd555
  2. pat> \d
  3. abc012dbcd555
  4. ~~~ ~~~

Если Вы удивились выводу программы, то обратитесь к списку в начале статьи: \d обозначает сравнение с одной цифрой.

Что если имеется больше чем один способ правильного сравнения шаблонов?

  1. str> foozboozer
  2. pat> f.*z
  3. foozboozer
  4. ~~~~~~~~

foozbooz было сравнимой последовательностью, вместо просто fooz , с регулярным выражениями возможно сравнение с длинными подстроками.

А вот и пример поиска строки со временем.

  1. str> Wed Feb 7 08:58:04 JST 1996
  2. pat> [0-9]+:[0-9]+(:[0-9]+)?
  3. Wed Feb 7 08:58:04 JST 1996
  4. ~~~~~~~~

"=~" является оператором сравнения для регулярных выражений. Он возвращает позицию найденной строки либо nil, если строка не была найдена шаблоном регулярного выражения.

Вам это нравится? Поделитесь в социальных сетях!

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь