regexp-examples 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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'
|