regexp-examples 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +39 -3
- data/coverage/.resultset.json +212 -173
- data/coverage/index.html +1219 -985
- data/lib/regexp-examples/backreferences.rb +11 -5
- data/lib/regexp-examples/constants.rb +30 -13
- data/lib/regexp-examples/exceptions.rb +1 -0
- data/lib/regexp-examples/groups.rb +3 -9
- data/lib/regexp-examples/helpers.rb +1 -1
- data/lib/regexp-examples/parser.rb +5 -1
- data/lib/regexp-examples/regexp_extensions.rb +3 -3
- data/lib/regexp-examples/repeaters.rb +12 -8
- data/lib/regexp-examples/version.rb +1 -1
- data/spec/regexp-examples_spec.rb +28 -2
- metadata +2 -2
@@ -2,18 +2,24 @@ module RegexpExamples
|
|
2
2
|
class BackReferenceReplacer
|
3
3
|
def substitute_backreferences(full_examples)
|
4
4
|
full_examples.map do |full_example|
|
5
|
-
|
6
|
-
full_example.
|
5
|
+
begin
|
6
|
+
while full_example.match(/__(\w+?)__/)
|
7
|
+
full_example.sub!(/__(\w+?)__/, find_backref_for(full_example, $1))
|
8
|
+
end
|
9
|
+
full_example
|
10
|
+
rescue RegexpExamples::BackrefNotFound
|
11
|
+
# For instance, one "full example" from /(a|(b)) \2/: "a __2__"
|
12
|
+
# should be rejected because the backref (\2) does not exist
|
13
|
+
nil
|
7
14
|
end
|
8
|
-
|
9
|
-
end
|
15
|
+
end.compact
|
10
16
|
end
|
11
17
|
|
12
18
|
private
|
13
19
|
def find_backref_for(full_example, group_id)
|
14
20
|
full_example.all_subgroups.detect do |subgroup|
|
15
21
|
subgroup.group_id == group_id
|
16
|
-
end
|
22
|
+
end || raise(RegexpExamples::BackrefNotFound)
|
17
23
|
end
|
18
24
|
|
19
25
|
end
|
@@ -1,18 +1,35 @@
|
|
1
1
|
module RegexpExamples
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
2
|
+
class ResultCountLimiters
|
3
|
+
# The maximum variance for any given repeater, to prevent a huge/infinite number of
|
4
|
+
# examples from being listed. For example, if @@max_repeater_variance = 2 then:
|
5
|
+
# .* is equivalent to .{0,2}
|
6
|
+
# .+ is equivalent to .{1,3}
|
7
|
+
# .{2,} is equivalent to .{2,4}
|
8
|
+
# .{,3} is equivalent to .{0,2}
|
9
|
+
# .{3,8} is equivalent to .{3,5}
|
10
|
+
MaxRepeaterVarianceDefault = 2
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
# Maximum number of characters returned from a char set, to reduce output spam
|
13
|
+
# For example, if @@max_group_results = 5 then:
|
14
|
+
# \d = ["0", "1", "2", "3", "4"]
|
15
|
+
# \w = ["a", "b", "c", "d", "e"]
|
16
|
+
MaxGroupResultsDefault = 5
|
17
|
+
|
18
|
+
class << self
|
19
|
+
attr_reader :max_repeater_variance, :max_group_results
|
20
|
+
def configure!(max_repeater_variance, max_group_results)
|
21
|
+
@max_repeater_variance = (max_repeater_variance || MaxRepeaterVarianceDefault)
|
22
|
+
@max_group_results = (max_group_results || MaxGroupResultsDefault)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.MaxRepeaterVariance
|
28
|
+
ResultCountLimiters.max_repeater_variance
|
29
|
+
end
|
30
|
+
def self.MaxGroupResults
|
31
|
+
ResultCountLimiters.max_group_results
|
32
|
+
end
|
16
33
|
|
17
34
|
module CharSets
|
18
35
|
Lower = Array('a'..'z')
|
@@ -16,12 +16,6 @@ module RegexpExamples
|
|
16
16
|
def all_subgroups
|
17
17
|
[self, subgroups].flatten.reject { |subgroup| subgroup.group_id.nil? }
|
18
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
19
|
end
|
26
20
|
|
27
21
|
class SingleCharGroup
|
@@ -120,7 +114,7 @@ module RegexpExamples
|
|
120
114
|
# itself
|
121
115
|
def result
|
122
116
|
strings = @groups.map {|repeater| repeater.result}
|
123
|
-
RegexpExamples
|
117
|
+
RegexpExamples.permutations_of_strings(strings).map do |result|
|
124
118
|
GroupResult.new(result, group_id)
|
125
119
|
end
|
126
120
|
end
|
@@ -137,8 +131,8 @@ module RegexpExamples
|
|
137
131
|
|
138
132
|
|
139
133
|
def result
|
140
|
-
left_result = RegexpExamples
|
141
|
-
right_result = RegexpExamples
|
134
|
+
left_result = RegexpExamples.map_results(@left_repeaters)
|
135
|
+
right_result = RegexpExamples.map_results(@right_repeaters)
|
142
136
|
left_result.concat(right_result).flatten.uniq.map do |result|
|
143
137
|
GroupResult.new(result)
|
144
138
|
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module RegexpExamples
|
2
2
|
class Parser
|
3
3
|
attr_reader :regexp_string
|
4
|
-
def initialize(regexp_string)
|
4
|
+
def initialize(regexp_string, options={})
|
5
5
|
@regexp_string = regexp_string
|
6
6
|
@num_groups = 0
|
7
7
|
@current_position = 0
|
8
|
+
RegexpExamples::ResultCountLimiters.configure!(
|
9
|
+
options[:max_repeater_variance],
|
10
|
+
options[:max_group_results]
|
11
|
+
)
|
8
12
|
end
|
9
13
|
|
10
14
|
def parse
|
@@ -1,8 +1,8 @@
|
|
1
1
|
class Regexp
|
2
2
|
module Examples
|
3
|
-
def examples
|
4
|
-
full_examples = RegexpExamples
|
5
|
-
RegexpExamples::Parser.new(source).parse
|
3
|
+
def examples(options={})
|
4
|
+
full_examples = RegexpExamples.map_results(
|
5
|
+
RegexpExamples::Parser.new(source, options).parse
|
6
6
|
)
|
7
7
|
RegexpExamples::BackReferenceReplacer.new.substitute_backreferences(full_examples)
|
8
8
|
end
|
@@ -6,14 +6,18 @@ module RegexpExamples
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def result(min_repeats, max_repeats)
|
9
|
-
group_results = @group.result[0 .. MaxGroupResults-1]
|
9
|
+
group_results = @group.result[0 .. RegexpExamples.MaxGroupResults-1]
|
10
10
|
results = []
|
11
11
|
min_repeats.upto(max_repeats) do |repeats|
|
12
|
-
|
13
|
-
results <<
|
12
|
+
if repeats.zero?
|
13
|
+
results << [ GroupResult.new('') ]
|
14
|
+
else
|
15
|
+
results << RegexpExamples.permutations_of_strings(
|
16
|
+
[group_results] * repeats
|
17
|
+
)
|
14
18
|
end
|
15
19
|
end
|
16
|
-
results.uniq
|
20
|
+
results.flatten.uniq
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
@@ -33,7 +37,7 @@ module RegexpExamples
|
|
33
37
|
end
|
34
38
|
|
35
39
|
def result
|
36
|
-
super(0, MaxRepeaterVariance)
|
40
|
+
super(0, RegexpExamples.MaxRepeaterVariance)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
@@ -43,7 +47,7 @@ module RegexpExamples
|
|
43
47
|
end
|
44
48
|
|
45
49
|
def result
|
46
|
-
super(1, MaxRepeaterVariance + 1)
|
50
|
+
super(1, RegexpExamples.MaxRepeaterVariance + 1)
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
@@ -63,9 +67,9 @@ module RegexpExamples
|
|
63
67
|
@min = min || 0
|
64
68
|
if max
|
65
69
|
# Prevent huge number of results in case of e.g. /.{1,100}/.examples
|
66
|
-
@max = smallest(max, @min + MaxRepeaterVariance)
|
70
|
+
@max = smallest(max, @min + RegexpExamples.MaxRepeaterVariance)
|
67
71
|
elsif has_comma
|
68
|
-
@max = @min + MaxRepeaterVariance
|
72
|
+
@max = @min + RegexpExamples.MaxRepeaterVariance
|
69
73
|
else
|
70
74
|
@max = @min
|
71
75
|
end
|
@@ -115,7 +115,9 @@ RSpec.describe Regexp, "#examples" do
|
|
115
115
|
/((ref2)ref1) \1 \2/,
|
116
116
|
/((ref1and2)) \1 \2/,
|
117
117
|
/(one)(two)(three)(four)(five)(six)(seven)(eight)(nine)(ten) \10\9\8\7\6\5\4\3\2\1/,
|
118
|
-
/(a?(b?(c?(d?(e?)))))
|
118
|
+
/(a?(b?(c?(d?(e?)))))/,
|
119
|
+
/(a)? \1/,
|
120
|
+
/(a|(b)) \2/
|
119
121
|
)
|
120
122
|
end
|
121
123
|
|
@@ -208,12 +210,36 @@ RSpec.describe Regexp, "#examples" do
|
|
208
210
|
/[^\h\H]/,
|
209
211
|
/[^\D0-9]/,
|
210
212
|
/[^\Wa-zA-Z0-9_]/,
|
211
|
-
/[^\d\D]*/,
|
212
213
|
/[^\d\D]+/,
|
213
214
|
/[^\d\D]{2}/,
|
214
215
|
/[^\d\D]word/
|
215
216
|
)
|
216
217
|
end
|
217
218
|
|
219
|
+
context "exact examples match" do
|
220
|
+
# More rigorous tests to assert that ALL examples are being listed
|
221
|
+
context "default options" do
|
222
|
+
it { expect(/[ab]{2}/.examples).to eq ["aa", "ab", "ba", "bb"] }
|
223
|
+
it { expect(/(a|b){2}/.examples).to eq ["aa", "ab", "ba", "bb"] }
|
224
|
+
it { expect(/a+|b?/.examples).to eq ["a", "aa", "aaa", "", "b"] }
|
225
|
+
end
|
226
|
+
context "max_repeater_variance option" do
|
227
|
+
it do
|
228
|
+
expect(/a+/.examples(max_repeater_variance: 5))
|
229
|
+
.to eq %w(a aa aaa aaaa aaaaa aaaaaa)
|
230
|
+
end
|
231
|
+
it do
|
232
|
+
expect(/a{4,8}/.examples(max_repeater_variance: 0))
|
233
|
+
.to eq %w(aaaa)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
context "max_group_results option" do
|
237
|
+
it do
|
238
|
+
expect(/\d/.examples(max_group_results: 10))
|
239
|
+
.to eq %w(0 1 2 3 4 5 6 7 8 9)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
218
244
|
end
|
219
245
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: regexp-examples
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Lord
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-01-
|
11
|
+
date: 2015-01-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|