# Regular Expressions in Ruby

# Special characters ., |, (, ), [, ], {, }, +, \, ^, $, *, and ? 
#
# Given that r and s are regular expressions that denoting L(r) and L(s)
# . 	- matches any single character
# r | s	- matches L(r) U L(s) i.e. matches strings that match either r or s
# r s	- matches L(r) L(s) i.e. matches strings of the form 
#                  xy   where x matches r and y matches y
# r?  	- matches zero or one occurrence of pattern (optional operator)
# r* 	- matches zero or more occurrences of strings that match r (Kleene)
# r+ 	- matches one or more occurrences of strings that match r
# (r)	- matches L(r) i.e., the same set ot strings that r matches
#	  Also collects strings matching r $1, $2, $3 ...
# Character Classes Table 6.1; POSIX character classes
# [ cl ]- matches any single character in the character list cl
# [ f-l ]- matches any single character in the range 'f' to 'l'
# {} 	- matches 
# \ 	- quote the special characters
# Anchors
# ^ 	- matches the start of a line
# $ 	- matches the end of a line
# \a 	- matches the beginning of a string
# \A 	- matches anywhere not at the beginning of a string
# \z	- matches the end of a string
# \Z	- matches anywhere not at the end of a string
# \b 	- matches at a word boundary
# \B	- matches anywhere not at a word boundary 
#
# Ruby regular expressions are objects of type regexp
# you may explicitly call the constructor, 
# or use the literal forms / pattern /
# or %r{ pattern }

# Show_regexp from Pickaxe book
# application examples also
#`
def show_regexp(a, re)
   if a =~ re
        "#{$`}<<#{$&}>>#{$'}"
   else
        "no match"
   end
end

puts show_regexp('very interesting', /t/)
puts show_regexp('kangaroo', /angar/) # => k<<angar>>oo
puts show_regexp('!@%&_=+', /%&/) # => !@<<%&>>_=+

puts show_regexp('yes | no', /\|/) # => yes <<|>> no
puts show_regexp('yes (no)', /\(no\)/) # => yes <<(no)>>
puts show_regexp('are you sure?', /e\?/) # => are you sur<<e?>>

puts show_regexp("this is\nthe time", /^the/) # => this is\n<<the>> time
puts show_regexp("this is\nthe time", /is/) # => this <<is>>\nthe time
puts show_regexp("this is\nthe time", /\Athis/) # => <<this>> is\nthe time
puts show_regexp("this is\nthe time", /\Athe/) # => no match

puts show_regexp("this is\nthe time", /\bis/) # => this <<is>>\nthe time
puts show_regexp("this is\nthe time", /\Bis/) # => th<<is>> is\nthe time

a = Regexp.new('^\s*[az]') # => /^\s*[az]/
b = /^\s*[az]/ # => /^\s*[az]/
c = %r{^\s*[az]} # => /^\s*[az]/

name = "Fats Waller"
name =~ /a/ # => 1
name =~ /z/ # => nil
/a/ =~ name # => 1

#
show_regexp("this is\nthe time", /\bis/) # => this <<is>>\nthe time
show_regexp("this is\nthe time", /\Bis/) # => th<<is>> is\nthe time


a = "red ball blue sky"
show_regexp(a, /d|e/) # => r<<e>>d ball blue sky
show_regexp(a, /al|lu/) # => red b<<al>>l blue sky
show_regexp(a, /red ball|angry sky/) # => <<red ball>> blue sky

show_regexp('banana', /an*/) # => b<<an>>ana
show_regexp('banana', /(an)*/) # => <<>>banana
show_regexp('banana', /(an)+/) # => b<<anan>>a

a = 'red ball blue sky'
show_regexp(a, /blue|red/) # => <<red>> ball blue sky
show_regexp(a, /(blue|red) \w+/) # => <<red ball>> blue sky
show_regexp(a, /(red|blue) \w+/) # => <<red ball>> blue sky
show_regexp(a, /red|blue \w+/) # => <<red>> ball blue sky

/(\d\d):(\d\d)(..)/ =~ "12:50am" # => 0 "Hour is #$1, minute #$2" # => "Hour is 12, minute 50"
/((\d\d):(\d\d))(..)/ =~ "12:50am" # => 0 "Time is #$1" # => "Time is 12:50"
"Hour is #$2, minute #$3" # => "Hour is 12, minute 50"
"AM/PM is #$4" # => "AM/PM is am"

###/(?<hour>\d\d):(?<min>\d\d)(..)/ =~ "12:50am" # => 0
###"Hour is #{hour}, minute #{min}" # => "Hour is 12, minute 50"

a = "the quick brown fox"
a.sub(/[aeiou]/, '*') # => "th* quick brown fox"
a.gsub(/[aeiou]/, '*') # => "th* q**ck br*wn f*x"
a.sub(/\s\S+/, '') # => "the brown fox"
a.gsub(/\s\S+/, '') # => "the"

