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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
# File 'lib/rmtools/text/regexp.rb', line 38
def reverse
return self if source.size == 1 or source.size == 2 && (source.ord == ?\\ or source[0] == source[1])
new = []
bs = klass = count = nil
group_marks = []
oppose = {'('=>')', ')'=>'(', '^'=>'$', '$'=>'^'}
borders = {'Z'=>'\A', 'A'=>'\Z', 'z'=>'\a', 'a'=>'\z'}
ext = options&2 != 0
StringScanner.each(source, /./) {|s|
$log << s.matched
$log << new
$log << {bs: bs, klass: klass, count: count, group_marks: group_marks}
puts '---'
if (m = s.matched) == '\\'
(klass || new) << '\\' if !(bs = !bs)
else
if bs
if !klass and m =~ /\d/
if m != '0' and s.+ !~ /\d/
raise RegexpError, "there is no meaning in use of groups \\#{m} inside of reversed regexp at #{s.pos-1}"
else
chars = s.check_until(/\D/)[0..-2]
new << ((m == '0' ? m : '0' << m) << chars).to_i(8).chr
s.pos += chars.size
end
elsif !klass and m == 'x'
chars = s.check_until(/[^a-f\d]/)[0..-2]
new << chars.to_i(16).chr
s.pos += chars.size
else
(klass || new) << ((b = borders[m]) ? b.dup : '\\' << m)
end
elsif ext and m =~ /\s/
next
elsif ext and m == '#'
s.scan_until(/\n\s*/)
else case m[0]
when ?[; klass = ''
when ?]; new << "[#{klass}]"; klass = nil
when ?{; klass ? klass << m : count = ''
when ?}; klass ? klass << m : _find_paren(new) << "{#{count}}"; count = nil
when ?^, ?$; klass ? klass << m : new << oppose[m]
when ?+, ?*; klass ? klass << m : _find_paren(new) << m
when ??
if new.last == ')'
group_marks << s.scan_until(/./)
else klass ? klass << m : _find_paren(new) << m
end
when ?)
gm = group_marks.pop
gm ? new << ('(?' << gm) : (klass || new) << '('
else (count || klass || new) << ((op = oppose[m]) ? op.dup : m)
end
end
bs = false
end
}
new.reverse.join.to_re
end
|