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.
@@ -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