Имаме следната задача:
Да се напише кратък Ruby expression, който проверява дали дадено число е просто или не, посредством употреба на регулярен израз. Резултатът от изпълнението му трябва да еtrue
за прости числа иfalse
за всички останали. Неща, които можете да ползвате:
- Самото число, разбира се.
- Произволни методи от класа
Regexp
- Подходящ регулярен израз (шаблон)
- Текстовия низ
'1'
.String#*
.- Някакъв условен оператор (например
if
-else
или? … : …
)true
,false
, ...
Материалът, необходим за решаването й, ще го има изцяло в днешната лекция.
Имаме следната задача:
Да валидирате изрази от следния тип за правилно отворени/затворени скоби:
(car (car (car ...)))
- Например:
(car (car (car (car list))))
- Целта е израз, чийто резултат да може да се ползва в условен оператор (
true
/false
-еквивалент)- Можете да ползвате произволни методи от класа
Regexp
- И регулярен израз, разбира се
Примерно решение — на някоя от следващите сбирки.
grep
, sed
, awk
, vi
, Emacs
...
Regexp
/pattern/
%r
, например: %r{/path/maching/made/easy}
Regexp
, а някои са в String
Regexp#match
nil
, ако шаблонът не "хваща" нищо
MatchData
, ако шаблонът "хваща" нещо от низа
MatchData
в детайли — по-късно
/dubstep/
ще отговаря на точно тази последователност от символи в низ
(
, )
, [
, ]
, {
, }
, .
, ?
, +
, *
, ^
, $
, \
, ...
-
)/find me/.match 'Can you find me in this long sentence?' # #<MatchData "find me">
/find me/.match 'I am not here and you will not find ME!' # nil
.
съвпада с един произволен символ (с изключение на символите за нов ред)
[
и ]
се ползват за дефиниране на класове от символи
*
, ?
, +
, {
и }
се ползват за указване на повторения
^
, $
, \b
, \B
и т.н. са "котви" и съответстват на определени "междусимволни дупки" :)
|
има смисъл на или, например:/day|nice/.match 'A nice dance-day.' # #<MatchData "nice">
/da(y|n)ce/.match 'A nice dance-day.' # #<MatchData "dance" 1:"n">
Внимавайте с приоритета на |
\
пред специален символ го прави неспециален такъв (екранира го)
\\
(като в обикновен низ)[
и ]
[a-z]
или [0-9A-F]
^
, това означава "някой символ, който не е посочен в класа"
[a\-b]
[-abc]
или [abc-]
- тук то няма специален смисъл
/W[aeiou]rd/.match "Word" # #<MatchData "Word">
/[0-9a-f]/.match '9f' # #<MatchData "9">
/[9f]/.match '9f' # #<MatchData "9">
/[^a-z]/.match '9f' # #<MatchData "9">
\w
- символ от дума ([a-zA-Z0-9_]
)
\W
- символ, който не може да участва в дума ([^a-zA-Z0-9_]
)
\d
- цифра ([0-9])
\D
- символ, който не е цифра ([^0-9]
)
\h
- шеснадесетична цифра ([0-9a-fA-F]
)
\H
- символ, който не е шеснадесетична цифра ([^0-9a-fA-F]
)
\s
- whitespace-символ (/[ \t\r\n\f]/
)
\S
- символ, който не е whitespace (/[^ \t\r\n\f]/
)[[:alpha:]]
- символ от азбука
[[:alnum:]]
- горното или цифра
[[:blank:]]
- интервал или таб
[[:cntrl:]]
- контролен символ
[[:digit:]]
- цифра
[[:lower:]]
- малка буква
[[:upper:]]
- главна буква
[[:print:]]
- printable-символ
[[:punct:]]
- пунктуационен символ
[[:space:]]
- whitespace-символ (вкл. и нов ред)
[[:xdigit:]]
- шеснадеситична цифра
[[:word:]]
- символ, който може да участва в дума (работи и за Unicode, за разлика от \w
)
[[:ascii:]]
- ASCII-символ\p{}
може да match-вате символи, имащи съответното свойство (подобно на POSIX)
\p{Alnum}
, \p{Alpha}
, \p{Blank}
, \p{Cntrl}
, \p{Digit}
, \p{Graph}
\p{Katakana}
\p{Cyrillic}
, например:/\s\p{Cyrillic}\p{Cyrillic}\p{Cyrillic}/.match 'Ние сме на всеки километър!' # #<MatchData " сме"># ~> -:1: invalid character property name {Cyrillic}: /\s\p{Cyrillic}\p{Cyrillic}\p{Cyrillic}/
# ~> -:1: invalid multibyte char (US-ASCII)
# ~> -:1: invalid multibyte char (US-ASCII)
^
съвпада с началото на ред
$
съвпада с края на ред
\A
съвпада с началото на текстов низ
\z
съвпада с края на низ
\b
отговаря на граница на дума (когато е извън [
и ]
; вътре означава backspace
)
\B
отговаря на място, което не е граница на дума/real/.match "surrealist" # #<MatchData "real">
/\Areal/.match "surrealist" # nil
/\band/.match "Demand" # nil
/\Band.+/.match "Supply and demand curve" # #<MatchData "and curve">
s
s*
означава нула или повече повторения на s
s+
търси едно или повече повторения на s
s?
съвпада с нула или едно повторение на s
s{m,n}
означава между m и n повторения на s
m
или n
:
s{,n}
има смисъл на нула до n
повторения, а s{m,}
— поне m
повторения/e+/.match 'Keeewl' # #<MatchData "eee">
/[Kke]+/.match 'Keeewl' # #<MatchData "Keee">
/\w+/.match '2038 - the year' # #<MatchData "2038">
/".*"/.match '"Quoted text!"' # #<MatchData "\"Quoted text!\"">
/[[:upper:]]+[[:lower:]]+l{2}o/.match 'Hello' # #<MatchData "Hello">
?
след повторителя
.*?
прави повторението не-алчно
/<.+>/.match("<a><b>") # #<MatchData "<a><b>">
/<.+?>/.match("<a><b>") # #<MatchData "<a>">
Символите (
и )
се използват за логическо групиране на части от шаблона с цел:
day
или dance
: /\bda(y|nce)\b/
Текстът, който match-ва частта на шаблона, оградена в скоби, може да се достъпва:
\1
за първата група, \2
за втората и т.н.
MatchData
-обекта
$1
, $2
...
'1' * числото =~ /някакъв регулярен израз/ ? false : true
'1' * 13 =~ /^1?$|^(11+?)\1+$/ ? false : true
Остават още интересни неща за регулярните изрази, част от които ще разгледаме на една от следващите сбирки.