regexp-examples 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/coverage/.resultset.json +79 -78
- data/coverage/coverage-badge.png +0 -0
- data/coverage/index.html +709 -687
- data/lib/regexp-examples/backreferences.rb +6 -37
- data/lib/regexp-examples/exceptions.rb +5 -0
- data/lib/regexp-examples/groups.rb +36 -10
- data/lib/regexp-examples/helpers.rb +2 -12
- data/lib/regexp-examples/parser.rb +2 -2
- data/lib/regexp-examples/regexp_extensions.rb +4 -6
- data/lib/regexp-examples/version.rb +1 -1
- data/regexp-examples.gemspec +1 -0
- data/spec/regexp-examples_spec.rb +17 -6
- metadata +4 -3
@@ -1,49 +1,18 @@
|
|
1
1
|
module RegexpExamples
|
2
|
-
class CaptureGroupResult < String
|
3
|
-
attr_reader :group_id, :subgroups
|
4
|
-
def initialize(group_id, subgroups, values)
|
5
|
-
@group_id = group_id
|
6
|
-
@subgroups = subgroups
|
7
|
-
super(values)
|
8
|
-
end
|
9
|
-
|
10
|
-
def all_subgroups
|
11
|
-
[self, subgroups].flatten
|
12
|
-
end
|
13
|
-
|
14
|
-
# Overridden in order to preserve the @group_id and @subgroups
|
15
|
-
def *(int)
|
16
|
-
self.class.new(group_id, subgroups, super)
|
17
|
-
end
|
18
|
-
# Overridden in order to preserve the @group_id and @subgroups
|
19
|
-
def gsub(regex)
|
20
|
-
self.class.new(group_id, subgroups, super)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
2
|
class BackReferenceReplacer
|
25
3
|
def substitute_backreferences(full_examples)
|
26
|
-
full_examples.map
|
27
|
-
|
28
|
-
|
29
|
-
else
|
30
|
-
full_example.map! do |partial_example|
|
31
|
-
partial_example.gsub(/__(\w+)__/) do |match|
|
32
|
-
find_backref_for(full_example, $1)
|
33
|
-
end
|
34
|
-
end
|
4
|
+
full_examples.map do |full_example|
|
5
|
+
while full_example.match(/__(\w+?)__/)
|
6
|
+
full_example.sub!(/__(\w+?)__/, find_backref_for(full_example, $1))
|
35
7
|
end
|
8
|
+
full_example
|
36
9
|
end
|
37
|
-
full_examples
|
38
10
|
end
|
39
11
|
|
40
12
|
private
|
41
13
|
def find_backref_for(full_example, group_id)
|
42
|
-
full_example.
|
43
|
-
|
44
|
-
partial_example.all_subgroups.each do |subgroup|
|
45
|
-
return subgroup if subgroup.group_id == group_id
|
46
|
-
end
|
14
|
+
full_example.all_subgroups.detect do |subgroup|
|
15
|
+
subgroup.group_id == group_id
|
47
16
|
end
|
48
17
|
end
|
49
18
|
|
@@ -1,10 +1,35 @@
|
|
1
1
|
module RegexpExamples
|
2
|
+
# All Group#result methods return an array of GroupResult objects
|
3
|
+
# The key objective here is to keep track of all capture groups, in order
|
4
|
+
# to fill in backreferences
|
5
|
+
class GroupResult < String
|
6
|
+
attr_reader :group_id, :subgroups
|
7
|
+
def initialize(result, group_id = nil, subgroups = [])
|
8
|
+
@group_id = group_id
|
9
|
+
@subgroups = subgroups
|
10
|
+
if result.respond_to?(:group_id)
|
11
|
+
@subgroups = result.all_subgroups
|
12
|
+
end
|
13
|
+
super(result)
|
14
|
+
end
|
15
|
+
|
16
|
+
def all_subgroups
|
17
|
+
[self, subgroups].flatten.reject { |subgroup| subgroup.group_id.nil? }
|
18
|
+
end
|
19
|
+
|
20
|
+
# Overridden in order to preserve the @group_id and @subgroups
|
21
|
+
# Used by BaseGroup (which, in turn, is used by all Group objects)
|
22
|
+
def *(int)
|
23
|
+
self.class.new(super.to_s, group_id, subgroups)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
2
27
|
class SingleCharGroup
|
3
28
|
def initialize(char)
|
4
29
|
@char = char
|
5
30
|
end
|
6
31
|
def result
|
7
|
-
[@char]
|
32
|
+
[GroupResult.new(@char)]
|
8
33
|
end
|
9
34
|
end
|
10
35
|
|
@@ -52,17 +77,17 @@ module RegexpExamples
|
|
52
77
|
end
|
53
78
|
|
54
79
|
def result
|
55
|
-
|
56
|
-
|
57
|
-
else
|
58
|
-
@chars
|
80
|
+
(@negative ? (CharSets::Any - @chars) : @chars).map do |result|
|
81
|
+
GroupResult.new(result)
|
59
82
|
end
|
60
83
|
end
|
61
84
|
end
|
62
85
|
|
63
86
|
class DotGroup
|
64
87
|
def result
|
65
|
-
CharSets::Any
|
88
|
+
CharSets::Any.map do |result|
|
89
|
+
GroupResult.new(result)
|
90
|
+
end
|
66
91
|
end
|
67
92
|
end
|
68
93
|
|
@@ -79,8 +104,7 @@ module RegexpExamples
|
|
79
104
|
def result
|
80
105
|
strings = @groups.map {|repeater| repeater.result}
|
81
106
|
RegexpExamples::permutations_of_strings(strings).map do |result|
|
82
|
-
|
83
|
-
group_id ? CaptureGroupResult.new(group_id, subgroups, result) : result
|
107
|
+
GroupResult.new(result, group_id)
|
84
108
|
end
|
85
109
|
end
|
86
110
|
end
|
@@ -101,7 +125,9 @@ module RegexpExamples
|
|
101
125
|
right_result = @right_repeaters.map do |repeater|
|
102
126
|
RegexpExamples::permutations_of_strings([repeater.result])
|
103
127
|
end
|
104
|
-
left_result.concat(right_result).flatten.uniq
|
128
|
+
left_result.concat(right_result).flatten.uniq.map do |result|
|
129
|
+
GroupResult.new(result)
|
130
|
+
end
|
105
131
|
end
|
106
132
|
end
|
107
133
|
|
@@ -112,7 +138,7 @@ module RegexpExamples
|
|
112
138
|
end
|
113
139
|
|
114
140
|
def result
|
115
|
-
["__#{@id}__"]
|
141
|
+
[ GroupResult.new("__#{@id}__") ]
|
116
142
|
end
|
117
143
|
end
|
118
144
|
|
@@ -11,26 +11,16 @@ module RegexpExamples
|
|
11
11
|
first = arrays_of_strings.shift
|
12
12
|
return first if arrays_of_strings.empty?
|
13
13
|
first.product( permutations_of_strings(arrays_of_strings, options) ).map do |result|
|
14
|
-
|
15
|
-
result.flatten
|
16
|
-
else
|
17
|
-
join_preserving_capture_groups(result)
|
18
|
-
end
|
14
|
+
join_preserving_capture_groups(result)
|
19
15
|
end
|
20
16
|
end
|
21
17
|
|
22
18
|
def self.join_preserving_capture_groups(result)
|
23
19
|
result.flatten!
|
24
20
|
subgroups = result
|
25
|
-
.select { |partial| partial.respond_to? :group_id }
|
26
21
|
.map(&:all_subgroups)
|
27
22
|
.flatten
|
28
|
-
|
29
|
-
if subgroups.empty?
|
30
|
-
result.join
|
31
|
-
else
|
32
|
-
CaptureGroupResult.new(nil, subgroups, result.join)
|
33
|
-
end
|
23
|
+
GroupResult.new(result.join, nil, subgroups)
|
34
24
|
end
|
35
25
|
end
|
36
26
|
|
@@ -92,9 +92,9 @@ module RegexpExamples
|
|
92
92
|
@current_position += 2
|
93
93
|
group_id = nil
|
94
94
|
when %w(! =).include?(match[2]) # e.g. /(?=lookahead)/, /(?!neglookahead)/
|
95
|
-
|
95
|
+
raise IllegalSyntaxError, "Lookaheads are not regular; cannot generate examples"
|
96
96
|
when %w(! =).include?(match[3]) # e.g. /(?<=lookbehind)/, /(?<!neglookbehind)/
|
97
|
-
|
97
|
+
raise IllegalSyntaxError, "Lookbehinds are not regular; cannot generate examples"
|
98
98
|
else # e.g. /(?<name>namedgroup)/
|
99
99
|
@current_position += (match[3].length + 3)
|
100
100
|
group_id = match[3]
|
@@ -3,12 +3,10 @@ class Regexp
|
|
3
3
|
def examples
|
4
4
|
partial_examples =
|
5
5
|
RegexpExamples::Parser.new(source)
|
6
|
-
|
7
|
-
|
8
|
-
full_examples = RegexpExamples::permutations_of_strings(partial_examples
|
9
|
-
|
10
|
-
RegexpExamples::BackReferenceReplacer.new.substitute_backreferences(full_examples)
|
11
|
-
full_examples_with_backrefs.map(&:join)
|
6
|
+
.parse
|
7
|
+
.map {|repeater| repeater.result}
|
8
|
+
full_examples = RegexpExamples::permutations_of_strings(partial_examples)
|
9
|
+
RegexpExamples::BackReferenceReplacer.new.substitute_backreferences(full_examples)
|
12
10
|
end
|
13
11
|
end
|
14
12
|
include Examples
|
data/regexp-examples.gemspec
CHANGED
@@ -13,6 +13,14 @@ RSpec.describe Regexp, "#examples" do
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def self.examples_raise_illegal_syntax_error(*regexps)
|
17
|
+
regexps.each do |regexp|
|
18
|
+
it do
|
19
|
+
expect{regexp.examples}.to raise_error RegexpExamples::IllegalSyntaxError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
16
24
|
context 'returns matching strings' do
|
17
25
|
context "for basic repeaters" do
|
18
26
|
examples_exist_and_match(
|
@@ -59,12 +67,6 @@ RSpec.describe Regexp, "#examples" do
|
|
59
67
|
/(?<name>namedgroup)/,
|
60
68
|
/(?<name>namedgroup) \k<name>/
|
61
69
|
)
|
62
|
-
# TODO: These are not yet implemented
|
63
|
-
# (expect to raise exception)
|
64
|
-
# /(?=lookahead)/,
|
65
|
-
# /(?!neglookahead)/,
|
66
|
-
# /(?<=lookbehind)/,
|
67
|
-
# /(?<!neglookbehind)/,
|
68
70
|
end
|
69
71
|
|
70
72
|
context "for escaped characters" do
|
@@ -109,5 +111,14 @@ RSpec.describe Regexp, "#examples" do
|
|
109
111
|
/a+|b*|c?/
|
110
112
|
)
|
111
113
|
end
|
114
|
+
|
115
|
+
context "for illegal syntax" do
|
116
|
+
examples_raise_illegal_syntax_error(
|
117
|
+
/(?=lookahead)/,
|
118
|
+
/(?!neglookahead)/,
|
119
|
+
/(?<=lookbehind)/,
|
120
|
+
/(?<!neglookbehind)/
|
121
|
+
)
|
122
|
+
end
|
112
123
|
end
|
113
124
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: regexp-examples
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Lord
|
@@ -82,6 +82,7 @@ files:
|
|
82
82
|
- lib/regexp-examples.rb
|
83
83
|
- lib/regexp-examples/backreferences.rb
|
84
84
|
- lib/regexp-examples/constants.rb
|
85
|
+
- lib/regexp-examples/exceptions.rb
|
85
86
|
- lib/regexp-examples/groups.rb
|
86
87
|
- lib/regexp-examples/helpers.rb
|
87
88
|
- lib/regexp-examples/parser.rb
|
@@ -103,7 +104,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
103
104
|
requirements:
|
104
105
|
- - ">="
|
105
106
|
- !ruby/object:Gem::Version
|
106
|
-
version:
|
107
|
+
version: 1.9.2
|
107
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
109
|
requirements:
|
109
110
|
- - ">="
|
@@ -111,7 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
112
|
version: '0'
|
112
113
|
requirements: []
|
113
114
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.
|
115
|
+
rubygems_version: 2.4.5
|
115
116
|
signing_key:
|
116
117
|
specification_version: 4
|
117
118
|
summary: Extends the Regexp class with '#examples'
|