string_pattern 2.1.4 → 2.2.3
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 +2 -0
- data/lib/string/pattern/add_to_ruby.rb +74 -65
- data/lib/string/pattern/analyze.rb +195 -0
- data/lib/string/pattern/generate.rb +579 -0
- data/lib/string/pattern/validate.rb +220 -0
- data/lib/string_pattern.rb +14 -987
- metadata +12 -10
@@ -0,0 +1,220 @@
|
|
1
|
+
class StringPattern
|
2
|
+
##############################################
|
3
|
+
# This method is defined to validate if the text_to_validate supplied follows the pattern
|
4
|
+
# It works also with array of patterns but in that case will return only true or false
|
5
|
+
# input:
|
6
|
+
# text (String) (synonyms: text_to_validate, validate) -- The text to validate
|
7
|
+
# pattern -- symbol with this info: "length:symbol_type" or "min_length-max_length:symbol_type"
|
8
|
+
# min_length -- minimum length of the string
|
9
|
+
# max_length (optional) -- maximum length of the string. If not provided the result will be with the min_length provided
|
10
|
+
# symbol_type -- the type of the string we want.
|
11
|
+
# expected_errors (Array of symbols) (optional) (synonyms: errors) -- :length, :min_length, :max_length, :value, :required_data, :excluded_data, :string_set_not_allowed
|
12
|
+
# not_expected_errors (Array of symbols) (optional) (synonyms: not_errors, non_expected_errors) -- :length, :min_length, :max_length, :value, :required_data, :excluded_data, :string_set_not_allowed
|
13
|
+
# example:
|
14
|
+
# validate(text: "This text will be validated", pattern: :"10-20:Xn", expected_errors: [:value, :max_length])
|
15
|
+
#
|
16
|
+
# Output:
|
17
|
+
# if expected_errors and not_expected_errors are not supplied: an array with all detected errors
|
18
|
+
# if expected_errors or not_expected_errors supplied: true or false
|
19
|
+
# if array of patterns supplied, it will return true or false
|
20
|
+
###############################################
|
21
|
+
def StringPattern.validate(text: "", pattern: "", expected_errors: [], not_expected_errors: [], **synonyms)
|
22
|
+
text_to_validate = text
|
23
|
+
text_to_validate = synonyms[:text_to_validate] if synonyms.keys.include?(:text_to_validate)
|
24
|
+
text_to_validate = synonyms[:validate] if synonyms.keys.include?(:validate)
|
25
|
+
expected_errors = synonyms[:errors] if synonyms.keys.include?(:errors)
|
26
|
+
not_expected_errors = synonyms[:not_errors] if synonyms.keys.include?(:not_errors)
|
27
|
+
not_expected_errors = synonyms[:non_expected_errors] if synonyms.keys.include?(:non_expected_errors)
|
28
|
+
#:length, :min_length, :max_length, :value, :required_data, :excluded_data, :string_set_not_allowed
|
29
|
+
if (expected_errors.include?(:min_length) or expected_errors.include?(:max_length)) and !expected_errors.include?(:length)
|
30
|
+
expected_errors.push(:length)
|
31
|
+
end
|
32
|
+
if (not_expected_errors.include?(:min_length) or not_expected_errors.include?(:max_length)) and !not_expected_errors.include?(:length)
|
33
|
+
not_expected_errors.push(:length)
|
34
|
+
end
|
35
|
+
if pattern.kind_of?(Array) and pattern.size == 1
|
36
|
+
pattern = pattern[0]
|
37
|
+
elsif pattern.kind_of?(Array) and pattern.size > 1
|
38
|
+
total_min_length = 0
|
39
|
+
total_max_length = 0
|
40
|
+
all_errors_collected = Array.new
|
41
|
+
result = true
|
42
|
+
num_patt = 0
|
43
|
+
patterns = Array.new
|
44
|
+
pattern.each { |pat|
|
45
|
+
if (pat.kind_of?(String) and (!StringPattern.optimistic or
|
46
|
+
(StringPattern.optimistic and pat.to_s.scan(/(\d+)-(\d+):(.+)/).size == 0 and pat.to_s.scan(/^!?(\d+):(.+)/).size == 0))) #fixed text
|
47
|
+
symbol_type = ""
|
48
|
+
min_length = max_length = pat.length
|
49
|
+
elsif pat.kind_of?(Symbol) or (pat.kind_of?(String) and StringPattern.optimistic and
|
50
|
+
(pat.to_s.scan(/(\d+)-(\d+):(.+)/).size > 0 or pat.to_s.scan(/^!?(\d+):(.+)/).size > 0))
|
51
|
+
#patt = Marshal.load(Marshal.dump(StringPattern.analyze(pat))) #deep copy
|
52
|
+
patt = StringPattern.analyze(pat).clone
|
53
|
+
min_length = patt.min_length.clone
|
54
|
+
max_length = patt.max_length.clone
|
55
|
+
symbol_type = patt.symbol_type.clone
|
56
|
+
else
|
57
|
+
puts "String pattern class not supported (#{pat.class} for #{pat})"
|
58
|
+
return false
|
59
|
+
end
|
60
|
+
|
61
|
+
patterns.push({ pattern: pat, min_length: min_length, max_length: max_length, symbol_type: symbol_type })
|
62
|
+
|
63
|
+
total_min_length += min_length
|
64
|
+
total_max_length += max_length
|
65
|
+
|
66
|
+
if num_patt == (pattern.size - 1) # i am in the last one
|
67
|
+
if text_to_validate.length < total_min_length
|
68
|
+
all_errors_collected.push(:length)
|
69
|
+
all_errors_collected.push(:min_length)
|
70
|
+
end
|
71
|
+
|
72
|
+
if text_to_validate.length > total_max_length
|
73
|
+
all_errors_collected.push(:length)
|
74
|
+
all_errors_collected.push(:max_length)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
num_patt += 1
|
78
|
+
}
|
79
|
+
|
80
|
+
num_patt = 0
|
81
|
+
patterns.each { |patt|
|
82
|
+
tmp_result = false
|
83
|
+
(patt[:min_length]..patt[:max_length]).each { |n|
|
84
|
+
res = StringPattern.validate(text: text_to_validate[0..n - 1], pattern: patt[:pattern], not_expected_errors: not_expected_errors)
|
85
|
+
if res.kind_of?(Array)
|
86
|
+
all_errors_collected += res
|
87
|
+
end
|
88
|
+
|
89
|
+
if res.kind_of?(TrueClass) or (res.kind_of?(Array) and res.size == 0) #valid
|
90
|
+
#we pass in the next one the rest of the pattern array list: pattern: pattern[num_patt+1..pattern.size]
|
91
|
+
res = StringPattern.validate(text: text_to_validate[n..text_to_validate.length], pattern: pattern[num_patt + 1..pattern.size], expected_errors: expected_errors, not_expected_errors: not_expected_errors)
|
92
|
+
|
93
|
+
if res.kind_of?(Array)
|
94
|
+
if ((all_errors_collected + res) - expected_errors).size > 0
|
95
|
+
tmp_result = false
|
96
|
+
else
|
97
|
+
all_errors_collected += res
|
98
|
+
tmp_result = true
|
99
|
+
end
|
100
|
+
elsif res.kind_of?(TrueClass)
|
101
|
+
tmp_result = true
|
102
|
+
end
|
103
|
+
return true if tmp_result
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
unless tmp_result
|
108
|
+
return false
|
109
|
+
end
|
110
|
+
num_patt += 1
|
111
|
+
}
|
112
|
+
return result
|
113
|
+
end
|
114
|
+
|
115
|
+
if (pattern.kind_of?(String) and (!StringPattern.optimistic or
|
116
|
+
(StringPattern.optimistic and pattern.to_s.scan(/(\d+)-(\d+):(.+)/).size == 0 and pattern.to_s.scan(/^!?(\d+):(.+)/).size == 0))) #fixed text
|
117
|
+
symbol_type = ""
|
118
|
+
min_length = max_length = pattern.length
|
119
|
+
else #symbol
|
120
|
+
#patt = Marshal.load(Marshal.dump(StringPattern.analyze(pattern))) #deep copy
|
121
|
+
patt = StringPattern.analyze(pattern).clone
|
122
|
+
min_length = patt.min_length.clone
|
123
|
+
max_length = patt.max_length.clone
|
124
|
+
symbol_type = patt.symbol_type.clone
|
125
|
+
|
126
|
+
required_data = patt.required_data.clone
|
127
|
+
excluded_data = patt.excluded_data.clone
|
128
|
+
string_set = patt.string_set.clone
|
129
|
+
all_characters_set = patt.all_characters_set.clone
|
130
|
+
|
131
|
+
required_chars = Array.new
|
132
|
+
required_data.each { |rd|
|
133
|
+
required_chars << rd if rd.size == 1
|
134
|
+
}
|
135
|
+
if (required_chars.flatten & excluded_data.flatten).size > 0
|
136
|
+
puts "pattern argument not valid on StringPattern.validate, a character cannot be required and excluded at the same time: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}"
|
137
|
+
return ""
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
if text_to_validate.nil?
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
detected_errors = Array.new
|
145
|
+
|
146
|
+
if text_to_validate.length < min_length
|
147
|
+
detected_errors.push(:min_length)
|
148
|
+
detected_errors.push(:length)
|
149
|
+
end
|
150
|
+
if text_to_validate.length > max_length
|
151
|
+
detected_errors.push(:max_length)
|
152
|
+
detected_errors.push(:length)
|
153
|
+
end
|
154
|
+
|
155
|
+
if symbol_type == "" #fixed text
|
156
|
+
if pattern.to_s != text.to_s #not equal
|
157
|
+
detected_errors.push(:value)
|
158
|
+
detected_errors.push(:required_data)
|
159
|
+
end
|
160
|
+
else # pattern supplied
|
161
|
+
if symbol_type != "@"
|
162
|
+
if required_data.size > 0
|
163
|
+
required_data.each { |rd|
|
164
|
+
if (text_to_validate.chars & rd).size == 0
|
165
|
+
detected_errors.push(:value)
|
166
|
+
detected_errors.push(:required_data)
|
167
|
+
break
|
168
|
+
end
|
169
|
+
}
|
170
|
+
end
|
171
|
+
if excluded_data.size > 0
|
172
|
+
if (excluded_data.flatten & text_to_validate.chars).size > 0
|
173
|
+
detected_errors.push(:value)
|
174
|
+
detected_errors.push(:excluded_data)
|
175
|
+
end
|
176
|
+
end
|
177
|
+
string_set_not_allowed = all_characters_set - string_set
|
178
|
+
text_to_validate.chars.each { |st|
|
179
|
+
if string_set_not_allowed.include?(st)
|
180
|
+
detected_errors.push(:value)
|
181
|
+
detected_errors.push(:string_set_not_allowed)
|
182
|
+
break
|
183
|
+
end
|
184
|
+
}
|
185
|
+
else #symbol_type=="@"
|
186
|
+
string = text_to_validate
|
187
|
+
wrong = %w(.. __ -- ._ _. .- -. _- -_ @. @_ @- .@ _@ -@ @@)
|
188
|
+
if !(Regexp.union(*wrong) === string) #don't include any or the wrong strings
|
189
|
+
if string.index("@").to_i > 0 and
|
190
|
+
string[0..(string.index("@") - 1)].scan(/([a-z0-9]+([\+\._\-][a-z0-9]|)*)/i).join == string[0..(string.index("@") - 1)] and
|
191
|
+
string[(string.index("@") + 1)..-1].scan(/([0-9a-z]+([\.-][a-z0-9]|)*)/i).join == string[string[(string.index("@") + 1)..-1]]
|
192
|
+
error_regular_expression = false
|
193
|
+
else
|
194
|
+
error_regular_expression = true
|
195
|
+
end
|
196
|
+
else
|
197
|
+
error_regular_expression = true
|
198
|
+
end
|
199
|
+
|
200
|
+
if error_regular_expression
|
201
|
+
detected_errors.push(:value)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
if expected_errors.size == 0 and not_expected_errors.size == 0
|
207
|
+
return detected_errors.uniq
|
208
|
+
else
|
209
|
+
if expected_errors & detected_errors == expected_errors
|
210
|
+
if (not_expected_errors & detected_errors).size > 0
|
211
|
+
return false
|
212
|
+
else
|
213
|
+
return true
|
214
|
+
end
|
215
|
+
else
|
216
|
+
return false
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|