| Class | OSC::Pattern |
| In: |
lib/osc/pattern.rb
|
| Parent: | String |
Do these two patterns intersect?
# File lib/osc/pattern.rb, line 48
48: def self.intersect?(s1,s2)
49: r = /\*|\?|\[[^\]]*\]|\{[^\}]*\}|./
50: a = s1.to_s.scan r
51: b = s2.to_s.scan r
52: q = [[a,b]]
53: until q.empty?
54: q.uniq!
55: a,b = q.pop
56: a = a.dup
57: b = b.dup
58:
59: return true if a.empty? and b.empty?
60: next if a.empty? or b.empty?
61:
62: x,y = a.shift, b.shift
63:
64: # branch {}
65: if x =~ /^\{/
66: x.scan /[^\{\},]+/ do |x|
67: q.push [x.scan(/./)+a,[y]+b]
68: end
69: next
70: end
71: if y =~ /^\{/
72: y.scan /[^\{\},]+/ do |y|
73: q.push [[x]+a,y.scan(/./)+b]
74: end
75: next
76: end
77:
78: # sort
79: if y =~ /^\[/
80: x,y = y,x
81: a,b = b,a
82: end
83: if y =~ /^(\*|\?)/
84: x,y = y,x
85: a,b = b,a
86: end
87:
88: # match
89: case x
90: when '*'
91: unless y == '/'
92: q.push [a,b]
93: q.push [[x]+a,b]
94: end
95: if y == '*'
96: q.push [a,[y]+b]
97: q.push [[x]+a,b]
98: end
99: when '?'
100: q.push [a,b] unless y == '/'
101: q.push [a,[y]+b] if y == '*'
102: when /^\[/
103: xinv = (x[1] == ?!)
104: yinv = (y =~ /^\[!/)
105: x = x[(xinv ? 2 : 1)..-2].scan(/./).to_set
106: if y =~ /^\[/
107: y = y[(yinv ? 2 : 1)..-2].scan(/./).to_set
108: else
109: y = [y].to_set
110: end
111:
112: # simplifying assumption: nobody in their right mind is going to do
113: # [^everyprintablecharacter]
114: if xinv and yinv
115: q.push [a,b]
116: elsif xinv and not yinv
117: q.push [a,b] unless (y-x).empty?
118: elsif not xinv and yinv
119: q.push [a,b] unless (x-y).empty?
120: else
121: q.push [a,b] unless (x&y).empty?
122: end
123: else
124: q.push [a,b] if x == y
125: end
126: end
127:
128: false # no intersection
129: end
Create an OSC pattern from a string or (experimental) from a Regex.
# File lib/osc/pattern.rb, line 5
5: def initialize(s)
6: case s
7: when Regexp # This is experimental
8: s = Regexp.source s
9: s.gsub! /(\\\\)*\[^\/\]\*/, "\1*"
10: s.gsub! /(\\\\)*\[^\/\]/, "\1?"
11: s.gsub! /(\\\\)*\[^/, "\1[!"
12: s.gsub! /(\\\\)*\(/, "\1{"
13: s.gsub! /(\\\\)*\|/, "\1,"
14: s.gsub! /(\\\\)*\)/, "\1}"
15: s.gsub! /\\\\/, "\\"
16: end
17: super s
18: end
Return a Regex representing this pattern
# File lib/osc/pattern.rb, line 21
21: def regexp
22: s = Regexp.escape self
23: s.gsub! /\\\?/, '[^/]'
24: s.gsub! /\\\*/, '[^/]*'
25: s.gsub! /\\\[!/, '[^'
26: s.gsub! /\\\]/, ']'
27: s.gsub! /\\\{/, '('
28: s.gsub! /,/, '|'
29: s.gsub! /\\\}/, ')'
30: Regexp.new s
31: end