Reputation: 27773
Using Ruby 1.8.7 I want to store some regular expressions in the database and have them be easily reconstituted as a Regexp
object when I need to use them for validation. I've found that Ruby exhibits some unwanted behavior. For instance:
r = Regexp.new(/^\w+$/i) => /^\w+$/i
r_i = r.inspect => "/^\\w+$/i"
r_s = r.to_s => "(?i-mx:^\\w+$)"
r_from_r_i = Regexp.new(r_i) => /\/^\w+$\/i/
r_from_r_s = Regexp.new(r_s) => /(?i-mx:^\w+$)/
r == r_from_r_i => false
r == r_from_r_s => false
What I'd like is to be able to store the Regexp
in the database in the form /pattern/options
instead of the (?options:pattern)
format, because I'm more familiar with the former. But, when creating a new Regexp
from a variable, the pattern gets all wacky. Ruby is escaping the /
s - so the pattern is invalid.
Is there any way to make Ruby honor the /pattern/options
format when parsing a regular expression?
Upvotes: 3
Views: 710
Reputation: 118261
You can do as below:
r = Regexp.new(/^\w+$/i) # => /^\w+$/i
source,option = r.source,r.options # => ["^\\w+$", 1]
regex = Regexp.new(source,option)
regex == r # => true
Returns the set of bits corresponding to the options used when creating this Regexp
Returns the original string of the pattern
Now, if you want a single variable to hold all your Regex details, then consider as below:
r = Regexp.new(/^\w+$/i) # => /^\w+$/i
source_option = r.source,r.options # => ["^\\w+$", 1]
regex = Regexp.new(*source_option)
regex == r # => true
Why did yours get
false
withto_s
orinspect
?
Read the doc carefully; you can see that Regexp.to_s
is saying:
Returns a string containing the regular expression and its options (using the (?opts:source) notation. This string can be fed back in to Regexp::new to a regular expression with the same semantics as the original. (However,
Regexp#==
may not return true when comparing the two, as the source of the regular expression itself may differ, as the example shows).Regexp#inspect
produces a generally more readable version of rxp.
Now, see:
r = Regexp.new(/^\w+$/i) # => /^\w+$/i
r_s = r.to_s
r_from_r_s = Regexp.new(r_s)
r == r_from_r_s # => false
# because the source strings are not same for r and r_from_r_s
r.source # => "^\\w+$"
r_from_r_s.source # => "(?i-mx:^\\w+$)"
The same explanation as above holds for the result of r == r_from_r_i
.
Upvotes: 8