blob: d0d8797008606e8cd59ef5f585a2783fb8accc47 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
require 'rack/mount/strexp/parser'
module Rack::Mount
class Strexp
class << self
# Parses segmented string expression and converts it into a Regexp
#
# Strexp.compile('foo')
# # => %r{\Afoo\Z}
#
# Strexp.compile('foo/:bar', {}, ['/'])
# # => %r{\Afoo/(?<bar>[^/]+)\Z}
#
# Strexp.compile(':foo.example.com')
# # => %r{\A(?<foo>.+)\.example\.com\Z}
#
# Strexp.compile('foo/:bar', {:bar => /[a-z]+/}, ['/'])
# # => %r{\Afoo/(?<bar>[a-z]+)\Z}
#
# Strexp.compile('foo(.:extension)')
# # => %r{\Afoo(\.(?<extension>.+))?\Z}
#
# Strexp.compile('src/*files')
# # => %r{\Asrc/(?<files>.+)\Z}
def compile(str, requirements = {}, separators = [], anchor = true)
return Regexp.compile(str) if str.is_a?(Regexp)
requirements = requirements ? requirements.dup : {}
normalize_requirements!(requirements, separators)
parser = StrexpParser.new
parser.anchor = anchor
parser.requirements = requirements
begin
re = parser.scan_str(str)
rescue Racc::ParseError => e
raise RegexpError, e.message
end
Regexp.compile(re)
end
alias_method :new, :compile
private
def normalize_requirements!(requirements, separators)
requirements.each do |key, value|
if value.is_a?(Regexp)
if regexp_has_modifiers?(value)
requirements[key] = value
else
requirements[key] = value.source
end
else
requirements[key] = Regexp.escape(value)
end
end
requirements.default ||= separators.any? ?
"[^#{separators.join}]+" : '.+'
requirements
end
def regexp_has_modifiers?(regexp)
regexp.options & (Regexp::IGNORECASE | Regexp::EXTENDED) != 0
end
end
end
end
|