Method: Faker::Base.regexify

Defined in:
lib/faker.rb

.regexify(reg) ⇒ Object

Given a regular expression, attempt to generate a string that would match it. This is a rather simple implementation, so don’t be shocked if it blows up on you in a spectacular fashion.

It does not handle ., *, unbounded ranges such as 1,, extensions such as (?=), character classes, some abbreviations for character classes, and nested parentheses.

I told you it was simple. :) It’s also probably dog-slow, so you shouldn’t use it.

It will take a regex like this:

/^[A-PR-UWYZ0-9][A-HK-Y0-9][AEHMNPRTVXY0-9]?[ABEHMNPRVWXY0-9]? 1,2[ABD-HJLN-UW-Z]2$/

and generate a string like this:

“U3V 3TP”



93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/faker.rb', line 93

def regexify(reg)
  reg = reg.source if reg.respond_to?(:source) # Handle either a Regexp or a String that looks like a Regexp
  reg
    .gsub(%r{^/?\^?}, '').gsub(%r{\$?/?$}, '') # Ditch the anchors
    .gsub(/\{(\d+)\}/, '{\1,\1}').gsub('?', '{0,1}') # All {2} become {2,2} and ? become {0,1}
    .gsub(/(\[[^\]]++\])\{(\d+),(\d+)\}/) { |_match| Regexp.last_match(1) * sample(Array(Range.new(Regexp.last_match(2).to_i, Regexp.last_match(3).to_i))) }                # [12]{1,2} becomes [12] or [12][12]
    .gsub(/(\([^)]++\))\{(\d+),(\d+)\}/) { |_match| Regexp.last_match(1) * sample(Array(Range.new(Regexp.last_match(2).to_i, Regexp.last_match(3).to_i))) }                 # (12|34){1,2} becomes (12|34) or (12|34)(12|34)
    .gsub(/(\\?.)\{(\d+),(\d+)\}/) { |_match| Regexp.last_match(1) * sample(Array(Range.new(Regexp.last_match(2).to_i, Regexp.last_match(3).to_i))) }                       # A{1,2} becomes A or AA or \d{3} becomes \d\d\d
    .gsub(/\((.*?)\)/) { |match| sample(match.gsub(/[()]/, '').split('|')) }                                                                                                # (this|that) becomes 'this' or 'that'
    .gsub(/\[([^\]]++)\]/) { |match| match.gsub(/(\w-\w)/) { |range| sample(Array(Range.new(*range.split('-')))) } }                                                        # All A-Z inside of [] become C (or X, or whatever)
    .gsub(/\[([^\]]++)\]/) { |_match| sample(Regexp.last_match(1).chars) }                                                                                                  # All [ABC] become B (or A or C)
    .gsub('\d') { |_match| sample(Numbers) }
    .gsub('\w') { |_match| sample(Letters) }
end