Каква е рализката между следните?
/(\w+), \g<1>/.match 'something, fishy' # => ?
/(\w+), \1/.match 'something, fishy' # => ?
Каква е рализката между следните?
/(\w+), \g<1>/.match 'something, fishy' # #<MatchData "something, fishy" 1:"fishy">
/(\w+), \1/.match 'something, fishy' # nil
\1
match-ва match-натото от първата група. \g<1>
преизпълнява pattern-а на групата.
Какъв ще бъде резултатът?
/(\b\w+\b\s){4}\g<1>/.match 'the right person in the wrong place...'
$1 # => ?
Какъв ще бъде резултатът?
/(\b\w+\b\s){4}\g<1>/.match 'the right person in the wrong place...'
$1 # "the "
$1
се променя при всяко ново match-ване на групата. В това число и когато я преизпълните рекурсивно.
Къде и колко (не е нужно точно число) ще се backtrack-не:
/.*?hi.*there/.match 'om, nom, nom... oh hi there...'
.*?
ще започне от 0 символа и ще увеличава с един за всичко преди hi
. .*
ще започне с целия низ след hi
и ще намаля с един, докато не стигне до началото на there
.
Regexp
(
, )
, [
, ]
, {
, }
, .
, ?
, +
, *
, ^
, $
, \
, ...
\
/foobar/
или %r(/some/path)
Проверете дали нещо е валиден математически израз
- Произволно цяло число
1337
- Променлива (малка латинска буква)
x
- Знак пред валиден израз (+, -)
-33 + 22 * -y
- Операция между валидни изрази (+, -, *, /)
x + y - 21 / 3
- Скоби, ограждащи валидни изрази
-x * (y + -5 * (7 - 13)) / 44 - 9000
validator = /^([-+]?(\d+|[a-z]|\(\g<1>\)|\g<1> [-+*\/] \g<1>))$/
valid = '-(3 + (x * (7 / y))) * (44 * y - z / 22)'
invalid = '((33 - 7) * x'
validator.match(valid) ? true : false
validator.match(invalid) ? true : false
/^([-+]?(\d+|[a-z]|\(\g<1>\)|\g<1> [-+*\/] \g<1>))$/# ~> -:1: never ending recursion: /^([-+]?(\d+|[a-z]|\(\g<1>\)|\g<1> [-+*\/] \g<1>))$/
validator = /^([-+]?(\d+|[a-z]|\(\g<1>\))( [-+*\/] \g<1>)?)$/
valid = '-(3 + (x * (7 / y))) * (44 * y - z / 22)'
invalid = '((33 - 7) * x'
validator.match(valid) ? true : false # true
validator.match(invalid) ? true : false # false
/(?=pattern)/
/(?!pattern)/
/(?<=pattern)/
/(?<!pattern)/
/(?<=<b>)\w+(?=<\/b>)/.match("Fortune favours the <b>bold</b>") # #<MatchData "bold">
Сменете * на % ако тя не е екранирана (escape-ната)
foo*
=>foo%
foo\*
=>foo\*
foo\\\\*
=>foo\\\\%
*\\\**
=>%\\\*%
"*\\**".gsub(/((?<!\\)(?:\\\\)*)\*/, '\1%') # "%\\*%"
\
, които нямат пред себе си \
*
и готово :)"*\\**".gsub(/\G([^*\\]*(?:\\.[^*\\]*)*)\*/, '\1%') # "%\\*%"
Между другото, регулярните изрази поддържат интерполация по подразбиране:
name = /[^@]+/
host = /\w+\.(com|net|org)/
email = /#{name}@#{host}/ # /(?-mix:[^@]+)@(?-mix:\w+\.(com|net|org))/
Regexp#match
$~
Regexp.last_match
Enumerable
MatchData#[група]
, където група
е номер или име на група, ви връща порцията текст, отговаряща на съответната група
MatchData#begin(група)
пък ви връща число — отместването спрямо началото на низа на порцията текст, отговаряща на съответната група
/(\w+)/.match('Some words')[1] # "Some"
/(\w+)/.match('Some words').begin(1) # 0
/(?<id>\d+)/.match('ID: 12345')[:id] # "12345"
/(?<id>\d+)/.match('ID: 12345').begin(:id) # 4
MatchData#pre_match
(същото като специалната променлива $`
) — текстът преди съвпадението
MatchData#post_match
(същото като специалната променлива $'
) — текстът след съвпадението
match = /(?<number>\d+)/.match 'ID: 12345 (new)'
match[:number] # "12345"
match.pre_match # "ID: "
match.post_match # " (new)"
$~
, $'
, $1
, $2
, $3
и прочее
match
Regexp#match
html = '<h1>Header</h1>' # или:
html = '<img src="http://my/image.src" alt="Kartman Makes Burgers" />'
case html
when /(<h(\d)>)(.+)<\/h\2>/
{header: $3, size: $2}
when /<a\s+href="([^"]+)">([^<]+)<\/a>/
{url: $1, text: $2}
when /<img\s+src="([^"]+)"\s+alt="([^"]+)"\s*\/>/
{image: $1, alt: $2}
else
'unrecognized tag'
end
# {:image=>"http://my/image.src", :alt=>"Kartman Makes Burgers"}
String#match
String#=~
и String#!~
String#sub
, String#gsub
и вариантите им с !
String#[]
и String#slice
- в някои от вариантите си приемат регулярен израз
String#index
и rindex
приемат и регулярен израз
String#partition
и rpartition
и други...'SomeTitleCase'.gsub /(^|[[:lower:]])([[:upper:]])/ do
[$1, $2.downcase].reject(&:empty?).join('_')
end
# "some_title_case"
Цитат от документацията:
A regexp can be matched against a string when they either share an encoding, or the regexp’s encoding is US-ASCII and the string’s encoding is ASCII-compatible.
Regexp#encoding
/something/u
за UTF-8
Rubyのお父さんはまつもとゆきひろさんです。
unicode_test = 'Rubyのお父さんはまつもとゆきひろさんです。'
/は[[:alpha:]]+さん/.match unicode_test # #<MatchData "はまつもとゆきひろさん">
\b
в Unicode-текст работи, когато границата на думата е лесно определима
/\b[[:alpha:]]\b/.match 'това и онова' # #<MatchData "и">
Rubyのお父さんはまつもとゆきひろさんです。
?Например:
'Ruby no otousan ha Matsumoto Yukihiro san desu.'.gsub(/(\b[[:alpha:]]+\b)/) { "[#{$1}]" }
# "[Ruby] [no] [otousan] [ha] [Matsumoto] [Yukihiro] [san] [desu]."
Но:
'Rubyのお父さんはまつもとゆきひろさんです。'.gsub(/(\b[[:alpha:]]+\b)/) { "[#{$1}]" }
# "[Rubyのお父さんはまつもとゆきひろさんです]。"
/pattern/flags
i
прави търсенето на съвпадение нечувствително към регистъра на буквите
u
кара шаблона да носи задължителна кодировка UTF-8
m
превръща шаблона в multiline-такъв (в този режим, например, .
ще съвпада и с нов ред)
(?(cond)yes|no)
cond
може да е референция към друга група в шаблона, или пък look-ahead/behind
regexp = /^(number)?\s*(?(1)\d+|[a-zA-Z]+)$/
regexp =~ "number 123" # 0
regexp =~ "foo" # 0
regexp =~ "number baz" # nil
Regexp
: http://www.ruby-doc.org/core-2.1.5/Regexp.html
MatchData
: http://www.ruby-doc.org/core-2.1.5/MatchData.html
String
: http://www.ruby-doc.org/core-2.1.5/String.html
ri
, например: ri Regexp#=~
Да се напише кратък Ruby expression, който проверява дали дадено число е просто или не, посредством употреба на регулярен израз. Резултатът от изпълнението му трябва да еtrue
за прости числа иfalse
за всички останали. Неща, които можете да ползвате:
- Самото число, разбира се.
- Произволни методи от класа
Regexp
- Подходящ регулярен израз (шаблон)
- Текстовия низ
'1'
.String#*
.- Някакъв условен оператор (например
if
-else
или? … : …
)true
,false
, ...
'1' * числото =~ /някакъв регулярен израз/ ? false : true
'1' * 13 =~ /^1?$|^(11+?)\1+$/ ? false : true
Like any...