regexer 1.0.0

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.
Files changed (29) hide show
  1. checksums.yaml +7 -0
  2. data/lib/regexer/exceptions/invalid_value_error.rb +12 -0
  3. data/lib/regexer/exceptions/no_block_given_error.rb +12 -0
  4. data/lib/regexer/models/pattern.rb +28 -0
  5. data/lib/regexer/pattern_builder.rb +201 -0
  6. data/lib/regexer/utils/handlers/base_handler.rb +18 -0
  7. data/lib/regexer/utils/handlers/quantifier_options_handlers/base.rb +24 -0
  8. data/lib/regexer/utils/handlers/quantifier_options_handlers/exactly_option_handler.rb +25 -0
  9. data/lib/regexer/utils/handlers/quantifier_options_handlers/min_max_option_handler.rb +31 -0
  10. data/lib/regexer/utils/handlers/quantifier_options_handlers/minimum_option_handler.rb +25 -0
  11. data/lib/regexer/utils/handlers/quantifier_options_handlers/no_option_handler.rb +24 -0
  12. data/lib/regexer/utils/handlers/single_entity_checker_value_handlers/base.rb +24 -0
  13. data/lib/regexer/utils/handlers/single_entity_checker_value_handlers/number_handler.rb +24 -0
  14. data/lib/regexer/utils/handlers/single_entity_checker_value_handlers/pattern_object_handler.rb +34 -0
  15. data/lib/regexer/utils/handlers/single_entity_checker_value_handlers/string_handler.rb +24 -0
  16. data/lib/regexer/utils/pattern_sanitizer.rb +20 -0
  17. data/lib/regexer/utils/quantifier_value_generator.rb +27 -0
  18. data/lib/regexer/utils/single_entity_checker.rb +23 -0
  19. data/lib/regexer/utils/string_helper.rb +15 -0
  20. data/lib/regexer/validators/any_character_in_validator.rb +36 -0
  21. data/lib/regexer/validators/ascii_character_validator.rb +27 -0
  22. data/lib/regexer/validators/consecutive_instances_of_options_value_validator.rb +26 -0
  23. data/lib/regexer/validators/contains_value_validator.rb +36 -0
  24. data/lib/regexer/validators/from_to_validator.rb +33 -0
  25. data/lib/regexer/validators/letter_validator.rb +27 -0
  26. data/lib/regexer/validators/number_validator.rb +27 -0
  27. data/lib/regexer/version.rb +5 -0
  28. data/lib/regexer.rb +9 -0
  29. metadata +131 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 92070599c885225a8466e24f2bf46d3b5aea40c2ec205e8da99af425bf00d4e3
4
+ data.tar.gz: 42ce090a8b56be47aa2ca63caf8ec4c85868ff7229c7fec327b02086413b2327
5
+ SHA512:
6
+ metadata.gz: 8040c4d4a11602ccdf7ad2059f0474d57890af8613ba678c911dd6f2699cff6a74b18b64fbe56ef3a8b86656f849b1520ff06c4fdc4f7b8a7686dd408d008c4a
7
+ data.tar.gz: 142da4ce9ad77977a7379e514be5206647b08eb727f0422fa31af97827a29d552ddd0ed687f6a79cdababf0be6f4e00481bbd336dbde4c8c79f0ad507a935653
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Regexer
4
+ module Exceptions
5
+ # An Exception Class For General Invalid Value Errors
6
+ class InvalidValueError < StandardError
7
+ def initialize(message = nil)
8
+ super(message)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Regexer
4
+ module Exceptions
5
+ # An Exception Class For no block given error
6
+ class NoBlockGivenError < StandardError
7
+ def initialize(message = nil)
8
+ super(message)
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Regexer
4
+ module Models
5
+ # The main model for the patterns being build by pattern builder
6
+ class Pattern
7
+ attr_reader :raw_pattern
8
+
9
+ def initialize(pattern, regex_escaped: true, single_entity: true)
10
+ @raw_pattern = pattern
11
+ @regex_escaped = regex_escaped
12
+ @single_entity = single_entity
13
+ end
14
+
15
+ def regex_escaped?
16
+ @regex_escaped
17
+ end
18
+
19
+ def single_entity?
20
+ @single_entity
21
+ end
22
+
23
+ def regex
24
+ /#{raw_pattern}/
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,201 @@
1
+ require "regexer/validators/from_to_validator"
2
+ require "regexer/validators/contains_value_validator"
3
+ require "regexer/validators/any_character_in_validator"
4
+ require "regexer/exceptions/no_block_given_error"
5
+ require "regexer/models/pattern"
6
+ require "regexer/utils/single_entity_checker"
7
+ require "regexer/utils/quantifier_value_generator"
8
+ require "regexer/utils/pattern_sanitizer"
9
+ require "regexer/utils/string_helper"
10
+ require "pry"
11
+
12
+ module Regexer
13
+ # A Class that contains core methods for building regex patterns
14
+ class PatternBuilder
15
+ def initialize(&block)
16
+ @final_pattern = ""
17
+ instance_exec(&block)
18
+ end
19
+
20
+ def result
21
+ Regexer::Models::Pattern.new(@final_pattern, single_entity: false)
22
+ end
23
+
24
+ private
25
+
26
+ # STRUCTS
27
+ ConsecutiveOptions = Struct.new(:exactly, :minimum, :maximum)
28
+
29
+ # SPECIAL FUNCTION CHARACTERS
30
+ # MOSTLY IMPLEMENTATION OF SPECIAL CHARACTERS IN REGEX
31
+ def starts_with(value)
32
+ pattern = contains(value)&.raw_pattern
33
+
34
+ pattern_object = Regexer::Models::Pattern.new(String.new(pattern).insert(0, "^"), single_entity: false)
35
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, pattern, pattern_object.raw_pattern)
36
+ pattern_object
37
+ end
38
+
39
+ def ends_with(value)
40
+ pattern = contains(value)&.raw_pattern
41
+
42
+ pattern_object = Regexer::Models::Pattern.new(String.new(pattern).insert(-1, "$"), single_entity: false)
43
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, pattern, pattern_object.raw_pattern)
44
+ pattern_object
45
+ end
46
+
47
+ # REGEX QUANTIFIERS
48
+ def has_consecutive_instances_of(value, exactly: nil, minimum: nil, maximum: nil)
49
+ pattern = contains(value)&.raw_pattern
50
+
51
+ quantifier_pattern = Regexer::Utils::QuantifierValueGenerator
52
+ .generate(ConsecutiveOptions.new(exactly, minimum, maximum))
53
+ pattern_object = Regexer::Models::Pattern.new(
54
+ String.new(pattern).insert(-1, quantifier_pattern),
55
+ single_entity: false
56
+ )
57
+
58
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, pattern, pattern_object.raw_pattern)
59
+ pattern_object
60
+ end
61
+
62
+ def has_none_or_consecutive_instances_of(value)
63
+ pattern = contains(value)&.raw_pattern
64
+
65
+ pattern_object = Regexer::Models::Pattern.new(String.new(pattern).insert(-1, "*"), single_entity: false)
66
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, pattern, pattern_object.raw_pattern)
67
+ pattern_object
68
+ end
69
+
70
+ def has_none_or_one_instance_of(value)
71
+ pattern = contains(value)&.raw_pattern
72
+
73
+ pattern_object = Regexer::Models::Pattern.new(String.new(pattern).insert(-1, "?"), single_entity: false)
74
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, pattern, pattern_object.raw_pattern)
75
+ pattern_object
76
+ end
77
+
78
+ # BASIC EASE OF USE PATTERNS
79
+ def has_letter(from:, to:)
80
+ Regexer::Validators::FromToValidator.valid_values?("letter", from, to)
81
+ pattern_object = Regexer::Models::Pattern.new("[#{from}-#{to}]")
82
+ @final_pattern += pattern_object.raw_pattern
83
+ pattern_object
84
+ end
85
+
86
+ def has_number(from:, to:)
87
+ Regexer::Validators::FromToValidator.valid_values?("number", from, to)
88
+ pattern_object = Regexer::Models::Pattern.new("[#{from}-#{to}]")
89
+ @final_pattern += pattern_object.raw_pattern
90
+ pattern_object
91
+ end
92
+
93
+ def has_ascii_character(from:, to:)
94
+ Regexer::Validators::FromToValidator.valid_values?("ascii_character", from, to)
95
+ pattern_object = Regexer::Models::Pattern.new("[#{Regexp.escape(from)}-#{Regexp.escape(to)}]")
96
+ @final_pattern += pattern_object.raw_pattern
97
+ pattern_object
98
+ end
99
+
100
+ def has_word_character
101
+ pattern_object = Regexer::Models::Pattern.new("\\w")
102
+ @final_pattern += pattern_object.raw_pattern
103
+ pattern_object
104
+ end
105
+
106
+ def _or_
107
+ pattern_object = Regexer::Models::Pattern.new("\|")
108
+ @final_pattern += pattern_object.raw_pattern
109
+ pattern_object
110
+ end
111
+
112
+ def has_whitespace_character
113
+ pattern_object = Regexer::Models::Pattern.new("\\s")
114
+ @final_pattern += pattern_object.raw_pattern
115
+ pattern_object
116
+ end
117
+
118
+ def has_digit_character
119
+ pattern_object = Regexer::Models::Pattern.new("\\d")
120
+ @final_pattern += pattern_object.raw_pattern
121
+ pattern_object
122
+ end
123
+
124
+ def has_alphanumeric_character
125
+ pattern_object = Regexer::Models::Pattern.new("[A-Za-z0-9]")
126
+ @final_pattern += pattern_object.raw_pattern
127
+ pattern_object
128
+ end
129
+
130
+ def has_any_character_except_new_line
131
+ pattern_object = Regexer::Models::Pattern.new(".")
132
+ @final_pattern += pattern_object.raw_pattern
133
+ pattern_object
134
+ end
135
+
136
+ def contains(value)
137
+ Regexer::Validators::ContainsValueValidator.value_valid?(value)
138
+
139
+ sanitized_pattern = Regexer::Utils::PatternSanitizer.sanitize(value)
140
+
141
+ pattern_object = if ::Regexer::Utils::SingleEntityChecker.single_entity?(value)
142
+ Regexer::Models::Pattern.new(sanitized_pattern)
143
+ else
144
+ Regexer::Models::Pattern.new("(#{sanitized_pattern})")
145
+ end
146
+
147
+ Regexer::Utils::StringHelper.update_string_pattern(
148
+ @final_pattern,
149
+ value.instance_of?(::Regexer::Models::Pattern) ? sanitized_pattern : "",
150
+ pattern_object.raw_pattern
151
+ )
152
+ pattern_object
153
+ end
154
+
155
+ def has_group(&block)
156
+ raise Regexer::Exceptions::NoBlockGivenError unless block_given?
157
+
158
+ value = Regexer::PatternBuilder.new(&block).result
159
+ sanitized_pattern = Regexer::Utils::PatternSanitizer.sanitize(value)
160
+ pattern_object = Regexer::Models::Pattern.new("(#{sanitized_pattern})")
161
+ Regexer::Utils::StringHelper.update_string_pattern(@final_pattern, sanitized_pattern, pattern_object.raw_pattern)
162
+ pattern_object
163
+ end
164
+
165
+ def has_any_character_in(*values)
166
+ combined_pattern = values.reduce("") do |pattern, value|
167
+ Regexer::Validators::AnyCharacterInValidator.value_valid?(value)
168
+ if value.instance_of?(Hash)
169
+ Regexer::Validators::FromToValidator.valid_values?("ascii_character", value[:from], value[:to])
170
+ pattern + "#{value[:from]}-#{value[:to]}"
171
+ else
172
+ pattern + Regexer::Utils::PatternSanitizer.sanitize(value)
173
+ end
174
+ end
175
+
176
+ pattern_object = Regexer::Models::Pattern.new("[#{combined_pattern}]")
177
+ @final_pattern += pattern_object.raw_pattern
178
+ pattern_object
179
+ end
180
+
181
+ # VALUE BUILDER METHOD THAT IS COMPATIBILE WITH THE PATTERN BUILDER
182
+ def character_range(from:, to:)
183
+ Regexer::Validators::FromToValidator.valid_values?("ascii_character", from, to)
184
+ { from: Regexp.escape(from), to: Regexp.escape(to) }
185
+ end
186
+
187
+ alias word_character has_word_character
188
+ alias whitespace_character has_whitespace_character
189
+ alias digit_character has_digit_character
190
+ alias alphanumeric_character has_alphanumeric_character
191
+ alias any_character_except_new_line has_any_character_except_new_line
192
+ alias letter has_letter
193
+ alias number has_number
194
+ alias ascii_character has_ascii_character
195
+ alias consecutive_instances_of has_consecutive_instances_of
196
+ alias none_or_consecutive_instances_of has_none_or_consecutive_instances_of
197
+ alias none_or_one_instance_of has_none_or_one_instance_of
198
+ alias group has_group
199
+ alias any_character_in has_any_character_in
200
+ end
201
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Regexer
4
+ module Utils
5
+ module Handlers
6
+ # A Base interface class for handlers
7
+ class BaseHandler
8
+ def handle
9
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
10
+ end
11
+
12
+ def next_handler(_handler)
13
+ raise NotImplementedError, "#{self.class} has not implemented method '#{__method__}'"
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/base_handler"
4
+
5
+ module Regexer
6
+ module Utils
7
+ module Handlers
8
+ module QuantifierOptionsHandler
9
+ # The base class for the quantifier options handler
10
+ class Base < ::Regexer::Utils::Handlers::BaseHandler
11
+ def next_handler(handler)
12
+ @next_handler = handler
13
+
14
+ handler
15
+ end
16
+
17
+ def give_to_next_handler(value)
18
+ @next_handler&.handle(value) if @next_handler
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/quantifier_options_handlers/base"
4
+ require "regexer/validators/consecutive_instances_of_options_value_validator"
5
+
6
+ module Regexer
7
+ module Utils
8
+ module Handlers
9
+ module QuantifierOptionsHandler
10
+ # A handler class to return the appropriate quantifier value
11
+ # if given the exactly option
12
+ class ExactlyOptionHandler < Base
13
+ def handle(value)
14
+ if value.exactly
15
+ Regexer::Validators::ConsecutiveInstancesOfOptionsValueValidator.value_valid?(value.exactly)
16
+ "{#{value.exactly}}"
17
+ else
18
+ give_to_next_handler(value)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/quantifier_options_handlers/base"
4
+ require "regexer/validators/consecutive_instances_of_options_value_validator"
5
+
6
+ module Regexer
7
+ module Utils
8
+ module Handlers
9
+ module QuantifierOptionsHandler
10
+ # A handler class to return the appropriate quantifier value
11
+ # if given the minimum & maximum options only
12
+ class MinMaxOptionHandler < Base
13
+ def handle(value)
14
+ if value.maximum
15
+ raise ArgumentError, "missing minimum keyword argument" unless value.minimum
16
+
17
+ Regexer::Validators::ConsecutiveInstancesOfOptionsValueValidator.value_valid?(value.minimum)
18
+ Regexer::Validators::ConsecutiveInstancesOfOptionsValueValidator.value_valid?(value.maximum)
19
+ Regexer::Validators::ConsecutiveInstancesOfOptionsValueValidator
20
+ .min_max_range_valid?(value.minimum, value.maximum)
21
+
22
+ "{#{value.minimum},#{value.maximum}}"
23
+ else
24
+ give_to_next_handler(value)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/quantifier_options_handlers/base"
4
+ require "regexer/validators/consecutive_instances_of_options_value_validator"
5
+
6
+ module Regexer
7
+ module Utils
8
+ module Handlers
9
+ module QuantifierOptionsHandler
10
+ # A handler class to return the appropriate quantifier value
11
+ # if given the minimum option only
12
+ class MinimumOptionHandler < Base
13
+ def handle(value)
14
+ if value.minimum && !value.maximum
15
+ Regexer::Validators::ConsecutiveInstancesOfOptionsValueValidator.value_valid?(value.minimum)
16
+ "{#{value.minimum},}"
17
+ else
18
+ give_to_next_handler(value)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/quantifier_options_handlers/base"
4
+ require "regexer/validators/consecutive_instances_of_options_value_validator"
5
+
6
+ module Regexer
7
+ module Utils
8
+ module Handlers
9
+ module QuantifierOptionsHandler
10
+ # A handler class to return the appropriate quantifier value
11
+ # if given no options
12
+ class NoOptionHandler < Base
13
+ def handle(value)
14
+ if !value.exactly && !value.minimum && !value.maximum
15
+ "+"
16
+ else
17
+ give_to_next_handler(value)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/base_handler"
4
+
5
+ module Regexer
6
+ module Utils
7
+ module Handlers
8
+ module SingleEntityCheckerValueHandler
9
+ # The base class for the single engtity checker value handler
10
+ class Base < ::Regexer::Utils::Handlers::BaseHandler
11
+ def next_handler(handler)
12
+ @next_handler = handler
13
+
14
+ handler
15
+ end
16
+
17
+ def give_to_next_handler(value)
18
+ @next_handler&.handle(value) if @next_handler
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/base"
4
+
5
+ module Regexer
6
+ module Utils
7
+ module Handlers
8
+ module SingleEntityCheckerValueHandler
9
+ # A handler class to check if a number is considered as single entity or not
10
+ # if this handler sees that the value is not a number, it will then pass it to
11
+ # the next handler
12
+ class NumberHandler < Base
13
+ def handle(value)
14
+ if value.instance_of?(Integer)
15
+ value.digits.length == 1
16
+ else
17
+ give_to_next_handler(value)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/base"
4
+
5
+ module Regexer
6
+ module Utils
7
+ module Handlers
8
+ module SingleEntityCheckerValueHandler
9
+ # A handler class to check if a pattern object is considered as single entity or not
10
+ # if this handler sees that the value is not a pattern object, it will then pass it to
11
+ # the next handler
12
+ class PatternObjectHandler < Base
13
+ def handle(value)
14
+ if value.instance_of?(::Regexer::Models::Pattern)
15
+ value.single_entity?
16
+ else
17
+ give_to_next_handler(value)
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def wrapped_in_parentheses?(value)
24
+ value.raw_pattern[0] == "(" && value.raw_pattern[-1] == ")"
25
+ end
26
+
27
+ def wrapped_in_square_brackets?(value)
28
+ value.raw_pattern[0] == "[" && value.raw_pattern[-1] == "]"
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/base"
4
+
5
+ module Regexer
6
+ module Utils
7
+ module Handlers
8
+ module SingleEntityCheckerValueHandler
9
+ # A handler class to check if a string value is considered as single entity or not
10
+ # if this handler sees that the value is not a string, it will then pass it to
11
+ # the next handler
12
+ class StringHandler < Base
13
+ def handle(value)
14
+ if value.instance_of?(String)
15
+ value.length == 1
16
+ else
17
+ give_to_next_handler(value)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/models/pattern"
4
+
5
+ module Regexer
6
+ module Utils
7
+ # A Utility Class that sanitizes a given value (mostly values given from the pattern builder)
8
+ # that is valid for regex
9
+ class PatternSanitizer
10
+ def self.sanitize(value)
11
+ if value.instance_of?(Regexer::Models::Pattern)
12
+ sanitize(value.raw_pattern) unless value.regex_escaped?
13
+ value.raw_pattern
14
+ else
15
+ Regexp.escape(value.to_s)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/quantifier_options_handlers/exactly_option_handler"
4
+ require "regexer/utils/handlers/quantifier_options_handlers/minimum_option_handler"
5
+ require "regexer/utils/handlers/quantifier_options_handlers/min_max_option_handler"
6
+ require "regexer/utils/handlers/quantifier_options_handlers/no_option_handler"
7
+
8
+ module Regexer
9
+ module Utils
10
+ # A Utility Class that generates a quantifier value based on
11
+ # the given options
12
+ class QuantifierValueGenerator
13
+ def self.generate(value)
14
+ exactly_option_handler = ::Regexer::Utils::Handlers::QuantifierOptionsHandler::ExactlyOptionHandler.new
15
+ minimum_option_handler = ::Regexer::Utils::Handlers::QuantifierOptionsHandler::MinimumOptionHandler.new
16
+ min_max_option_handler = ::Regexer::Utils::Handlers::QuantifierOptionsHandler::MinMaxOptionHandler.new
17
+ no_option_handler = ::Regexer::Utils::Handlers::QuantifierOptionsHandler::NoOptionHandler.new
18
+
19
+ exactly_option_handler.next_handler(minimum_option_handler)
20
+ .next_handler(min_max_option_handler)
21
+ .next_handler(no_option_handler)
22
+
23
+ exactly_option_handler.handle(value) || ""
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/string_handler"
4
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/number_handler"
5
+ require "regexer/utils/handlers/single_entity_checker_value_handlers/pattern_object_handler"
6
+
7
+ module Regexer
8
+ module Utils
9
+ # A Utility Class that checks if a value is a single entity or not
10
+ class SingleEntityChecker
11
+ def self.single_entity?(value)
12
+ string_handler = ::Regexer::Utils::Handlers::SingleEntityCheckerValueHandler::StringHandler.new
13
+ number_handler = ::Regexer::Utils::Handlers::SingleEntityCheckerValueHandler::NumberHandler.new
14
+ pattern_object_handler = ::Regexer::Utils::Handlers::SingleEntityCheckerValueHandler::PatternObjectHandler.new
15
+
16
+ string_handler.next_handler(number_handler)
17
+ .next_handler(pattern_object_handler)
18
+
19
+ string_handler.handle(value) || false
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,15 @@
1
+ module Regexer
2
+ module Utils
3
+ # A Utility Class that contains helper methods
4
+ # in dealing with strings
5
+ class StringHelper
6
+ def self.update_string_pattern(pattern_to_update, previous_appended_pattern, new_pattern)
7
+ if !previous_appended_pattern.empty? && pattern_to_update.end_with?(previous_appended_pattern)
8
+ pattern_to_update.sub!(/(#{Regexp.escape(previous_appended_pattern)})$/) { new_pattern }
9
+ else
10
+ pattern_to_update << new_pattern
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+ require "regexer/models/pattern"
5
+
6
+ module Regexer
7
+ module Validators
8
+ # A Validator Class for validating values being passed to has_any_character_in Regexer::Pattern method
9
+ class AnyCharacterInValidator
10
+ def self.value_valid?(value)
11
+ error_message = "Value should only be of type String or Integer or Hash with from & to keys"
12
+ raise Regexer::Exceptions::InvalidValueError, error_message unless valid?(value)
13
+ end
14
+
15
+ class << self
16
+ private
17
+
18
+ def number?(value)
19
+ value.instance_of?(Integer) || value.instance_of?(Float)
20
+ end
21
+
22
+ def string?(value)
23
+ value.instance_of?(String)
24
+ end
25
+
26
+ def from_to_hash?(value)
27
+ value.instance_of?(Hash) && value.keys == %i[from to]
28
+ end
29
+
30
+ def valid?(value)
31
+ number?(value) || string?(value) || from_to_hash?(value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+
5
+ module Regexer
6
+ module Validators
7
+ # A Validator Class for validating if a value is a single letter
8
+ class AsciiCharacterValidator
9
+ def self.ascii_character?(value)
10
+ error_message = "Value should only be a single character in the ascii table"
11
+ raise Regexer::Exceptions::InvalidValueError, error_message unless string?(value) && single_ascii_letter?(value)
12
+ end
13
+
14
+ class << self
15
+ private
16
+
17
+ def string?(value)
18
+ value.instance_of?(String)
19
+ end
20
+
21
+ def single_ascii_letter?(value)
22
+ value.length == 1 && value.match?(/[[:ascii:]]/)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+
5
+ module Regexer
6
+ module Validators
7
+ # A Validator Class for validating option values being passed to consecutive_instances_of Regexer::Pattern method
8
+ class ConsecutiveInstancesOfOptionsValueValidator
9
+ def self.value_valid?(value)
10
+ error_message = "Value should only be of type Integer"
11
+
12
+ raise Regexer::Exceptions::InvalidValueError, error_message unless integer?(value)
13
+ end
14
+
15
+ def self.min_max_range_valid?(min_value, max_value)
16
+ error_message = "minimum value is larger than maximum value"
17
+
18
+ raise RangeError, error_message unless min_value < max_value
19
+ end
20
+
21
+ private_class_method def self.integer?(value)
22
+ value.instance_of?(Integer)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+ require "regexer/models/pattern"
5
+
6
+ module Regexer
7
+ module Validators
8
+ # A Validator Class for validating values being passed to contains Regexer::Pattern method
9
+ class ContainsValueValidator
10
+ def self.value_valid?(value)
11
+ error_message = "Value should only be of type String or Integer or Float or Regexer::Models::Pattern"
12
+ raise Regexer::Exceptions::InvalidValueError, error_message unless valid?(value)
13
+ end
14
+
15
+ class << self
16
+ private
17
+
18
+ def number?(value)
19
+ value.instance_of?(Integer) || value.instance_of?(Float)
20
+ end
21
+
22
+ def string?(value)
23
+ value.instance_of?(String)
24
+ end
25
+
26
+ def pattern?(value)
27
+ value.instance_of?(Regexer::Models::Pattern)
28
+ end
29
+
30
+ def valid?(value)
31
+ number?(value) || string?(value) || pattern?(value)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/validators/letter_validator"
4
+ require "regexer/validators/number_validator"
5
+ require "regexer/validators/ascii_character_validator"
6
+
7
+ module Regexer
8
+ module Validators
9
+ # A Validator Class for validating range values in Regexer::Pattern methods
10
+ # that takes in from and to values as method arguments
11
+ class FromToValidator
12
+ def self.valid_values?(value_type, from_value, to_value)
13
+ case value_type
14
+ when "number"
15
+ Regexer::Validators::NumberValidator.number?(from_value)
16
+ Regexer::Validators::NumberValidator.number?(to_value)
17
+ when "letter"
18
+ Regexer::Validators::LetterValidator.letter?(from_value)
19
+ Regexer::Validators::LetterValidator.letter?(to_value)
20
+ when "ascii_character"
21
+ Regexer::Validators::AsciiCharacterValidator.ascii_character?(from_value)
22
+ Regexer::Validators::AsciiCharacterValidator.ascii_character?(to_value)
23
+ end
24
+
25
+ validate_range(from_value, to_value)
26
+ end
27
+
28
+ private_class_method def self.validate_range(from_value, to_value)
29
+ raise RangeError, "From value is greater than the To value" if from_value > to_value
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+
5
+ module Regexer
6
+ module Validators
7
+ # A Validator Class for validating if a value is a single letter
8
+ class LetterValidator
9
+ def self.letter?(value)
10
+ error_message = "Value should only be a single letter"
11
+ raise Regexer::Exceptions::InvalidValueError, error_message unless string?(value) && single_letter?(value)
12
+ end
13
+
14
+ class << self
15
+ private
16
+
17
+ def string?(value)
18
+ value.instance_of?(String)
19
+ end
20
+
21
+ def single_letter?(value)
22
+ value.length == 1 && value.match?(/[[:alpha:]]/)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "regexer/exceptions/invalid_value_error"
4
+
5
+ module Regexer
6
+ module Validators
7
+ # A Validator Class for validating if a value is an integer from 0 - 9
8
+ class NumberValidator
9
+ def self.number?(value)
10
+ error_message = "Value should only be an integer from 0 to 9"
11
+ raise Regexer::Exceptions::InvalidValueError, error_message unless integer?(value) && in_0_to_9?(value)
12
+ end
13
+
14
+ class << self
15
+ private
16
+
17
+ def integer?(value)
18
+ value.instance_of?(Integer)
19
+ end
20
+
21
+ def in_0_to_9?(value)
22
+ (0..9).to_a.include?(value)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Regexer
4
+ VERSION = "1.0.0"
5
+ end
data/lib/regexer.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "regexer/version"
4
+ require "regexer/pattern_builder"
5
+
6
+ module Regexer
7
+ class Error < StandardError; end
8
+ # Your code goes here...
9
+ end
metadata ADDED
@@ -0,0 +1,131 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: regexer
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Genesis Ivan Ilagan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: pry
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.13.1
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.13.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '13.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '13.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.7'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.7'
69
+ description: A ruby DSL for building regex patterns in a human readable format. Regexer
70
+ aims in making regex more easily read, learned and understood at first glance. Syntax
71
+ wise, it is inspired by FactoryBot and RSpec
72
+ email:
73
+ - ivanilagan1109@gmail.com
74
+ executables: []
75
+ extensions: []
76
+ extra_rdoc_files: []
77
+ files:
78
+ - lib/regexer.rb
79
+ - lib/regexer/exceptions/invalid_value_error.rb
80
+ - lib/regexer/exceptions/no_block_given_error.rb
81
+ - lib/regexer/models/pattern.rb
82
+ - lib/regexer/pattern_builder.rb
83
+ - lib/regexer/utils/handlers/base_handler.rb
84
+ - lib/regexer/utils/handlers/quantifier_options_handlers/base.rb
85
+ - lib/regexer/utils/handlers/quantifier_options_handlers/exactly_option_handler.rb
86
+ - lib/regexer/utils/handlers/quantifier_options_handlers/min_max_option_handler.rb
87
+ - lib/regexer/utils/handlers/quantifier_options_handlers/minimum_option_handler.rb
88
+ - lib/regexer/utils/handlers/quantifier_options_handlers/no_option_handler.rb
89
+ - lib/regexer/utils/handlers/single_entity_checker_value_handlers/base.rb
90
+ - lib/regexer/utils/handlers/single_entity_checker_value_handlers/number_handler.rb
91
+ - lib/regexer/utils/handlers/single_entity_checker_value_handlers/pattern_object_handler.rb
92
+ - lib/regexer/utils/handlers/single_entity_checker_value_handlers/string_handler.rb
93
+ - lib/regexer/utils/pattern_sanitizer.rb
94
+ - lib/regexer/utils/quantifier_value_generator.rb
95
+ - lib/regexer/utils/single_entity_checker.rb
96
+ - lib/regexer/utils/string_helper.rb
97
+ - lib/regexer/validators/any_character_in_validator.rb
98
+ - lib/regexer/validators/ascii_character_validator.rb
99
+ - lib/regexer/validators/consecutive_instances_of_options_value_validator.rb
100
+ - lib/regexer/validators/contains_value_validator.rb
101
+ - lib/regexer/validators/from_to_validator.rb
102
+ - lib/regexer/validators/letter_validator.rb
103
+ - lib/regexer/validators/number_validator.rb
104
+ - lib/regexer/version.rb
105
+ homepage: https://github.com/IvanIlagan/regexer-ruby
106
+ licenses:
107
+ - MIT
108
+ metadata:
109
+ homepage_uri: https://github.com/IvanIlagan/regexer-ruby
110
+ source_code_uri: https://github.com/IvanIlagan/regexer-ruby
111
+ changelog_uri: https://github.com/IvanIlagan/regexer-ruby/blob/main/CHANGELOG.md
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: 2.5.0
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.2.22
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: A ruby DSL for generating regex patterns
131
+ test_files: []