no_regex 0.1.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.
- checksums.yaml +7 -0
- data/README.md +10 -0
- data/lib/no_regex/aliases.rb +4 -0
- data/lib/no_regex/numeric_extensions.rb +140 -0
- data/lib/no_regex/pattern_methods.rb +109 -0
- data/lib/no_regex/rails_validators.rb +77 -0
- data/lib/no_regex/string_extensions.rb +149 -0
- data/lib/no_regex/version.rb +6 -0
- data/lib/no_regex.rb +19 -0
- metadata +94 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a468f27fb587ec14c92c7a9164acc0afbe38f904fbc765bd206d589cc5e90c4e
|
4
|
+
data.tar.gz: 3c6b9c9d8c6179034637022cc010bfd19ff02968ca5a8bf174fb8ac548b7058f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1f380a614f7a93833d25e748240033b7ef88585140f0a4b2289c402f4336a1b974eff1ffcfa312ceec15831b07193941b7d3ec268cf6655ff44b16c61b35ea10
|
7
|
+
data.tar.gz: 21083b7f2f777552af3541f00e0a9f8a4cf99f65e0c98d29b7904f5f0509842118a88b94a06eb3e41e07600feddd8d31c10529fd5ce92a803231904aaeba4b6a
|
data/README.md
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# NoRegex
|
2
|
+
|
3
|
+
Write Ruby without regex! A gem that provides simple, readable methods to replace complex regular expressions for string validation and manipulation.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'no_regex'
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extensions for Integer class
|
4
|
+
class Integer
|
5
|
+
def is_positive?
|
6
|
+
self > 0
|
7
|
+
end
|
8
|
+
|
9
|
+
def is_negative?
|
10
|
+
self < 0
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_zero?
|
14
|
+
self == 0
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_even?
|
18
|
+
(self % 2).zero?
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_odd?
|
22
|
+
!is_even?
|
23
|
+
end
|
24
|
+
|
25
|
+
def to_currency(symbol = "$")
|
26
|
+
"#{symbol}#{self}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_formatted
|
30
|
+
self.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\\1,').reverse
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_hex
|
34
|
+
"0x#{self.to_s(16).upcase}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_binary
|
38
|
+
"0b#{self.to_s(2)}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def to_words
|
42
|
+
# Simple implementation for numbers 0-999
|
43
|
+
return "zero" if self == 0
|
44
|
+
|
45
|
+
ones = ["", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
|
46
|
+
teens = ["ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"]
|
47
|
+
tens = ["", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"]
|
48
|
+
|
49
|
+
num = self.abs
|
50
|
+
result = []
|
51
|
+
|
52
|
+
if num >= 100
|
53
|
+
result << "#{ones[num / 100]} hundred"
|
54
|
+
num %= 100
|
55
|
+
end
|
56
|
+
|
57
|
+
if num >= 20
|
58
|
+
result << tens[num / 10]
|
59
|
+
num %= 10
|
60
|
+
elsif num >= 10
|
61
|
+
result << teens[num - 10]
|
62
|
+
num = 0
|
63
|
+
end
|
64
|
+
|
65
|
+
result << ones[num] if num > 0
|
66
|
+
|
67
|
+
word = result.join(" ").strip
|
68
|
+
self < 0 ? "negative #{word}" : word
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Extensions for Float class
|
73
|
+
class Float
|
74
|
+
def is_positive?
|
75
|
+
self > 0
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_negative?
|
79
|
+
self < 0
|
80
|
+
end
|
81
|
+
|
82
|
+
def is_zero?
|
83
|
+
self.zero?
|
84
|
+
end
|
85
|
+
|
86
|
+
def to_currency(symbol = "$", decimals = 2)
|
87
|
+
"#{symbol}#{'%.2f' % self.round(decimals)}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def to_percentage(decimals = 1)
|
91
|
+
"#{'%.1f' % (self * 100).round(decimals)}%"
|
92
|
+
end
|
93
|
+
|
94
|
+
def round_to(decimals)
|
95
|
+
(self * 10**decimals).round / 10.0**decimals
|
96
|
+
end
|
97
|
+
|
98
|
+
def is_integer?
|
99
|
+
self == self.to_i
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Extensions for NilClass
|
104
|
+
class NilClass
|
105
|
+
def is_blank?
|
106
|
+
true
|
107
|
+
end
|
108
|
+
|
109
|
+
def is_number?
|
110
|
+
false
|
111
|
+
end
|
112
|
+
|
113
|
+
def is_letters?
|
114
|
+
false
|
115
|
+
end
|
116
|
+
|
117
|
+
def is_email?
|
118
|
+
false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Extensions for Array
|
123
|
+
class Array
|
124
|
+
def all_numbers?
|
125
|
+
return false if empty?
|
126
|
+
all? { |item| item.to_s.match?(/\A-?\d+(\.\d+)?\z/) }
|
127
|
+
end
|
128
|
+
|
129
|
+
def all_strings?
|
130
|
+
all? { |item| item.is_a?(String) }
|
131
|
+
end
|
132
|
+
|
133
|
+
def extract_numbers
|
134
|
+
select { |item| item.to_s.match?(/\A-?\d+(\.\d+)?\z/) }.map(&:to_f)
|
135
|
+
end
|
136
|
+
|
137
|
+
def extract_emails
|
138
|
+
select { |item| item.to_s.match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i) }
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NoRegex
|
4
|
+
module PatternMethods
|
5
|
+
# Define methods that return regex patterns
|
6
|
+
def is_number?
|
7
|
+
# Examples: "12345", "0", "999"
|
8
|
+
/\A\d+\z/
|
9
|
+
end
|
10
|
+
|
11
|
+
def is_letters?
|
12
|
+
# Examples: "hello", "World", "ABC"
|
13
|
+
/\A[a-zA-Z]+\z/
|
14
|
+
end
|
15
|
+
|
16
|
+
def is_alphanumeric?
|
17
|
+
# Examples: "abc123", "Test99", "2024Year"
|
18
|
+
/\A[a-zA-Z0-9]+\z/
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_email?
|
22
|
+
# Examples: "user@example.com", "john.doe+tag@company.co.uk"
|
23
|
+
/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_url?
|
27
|
+
# Examples: "https://example.com", "www.site.org", "subdomain.example.com/path"
|
28
|
+
/\A(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?\z/
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_phone_number?
|
32
|
+
# Examples: "+1 555-123-4567", "555 123 4567", "(555) 123-4567"
|
33
|
+
/\A\+?[\d\s\-\(\)]+\z/
|
34
|
+
end
|
35
|
+
|
36
|
+
def is_zip_code?
|
37
|
+
# Examples: "12345", "12345-6789"
|
38
|
+
/\A\d{5}(-\d{4})?\z/
|
39
|
+
end
|
40
|
+
|
41
|
+
def is_hex_color?
|
42
|
+
# Examples: "#FF5733", "FF5733", "#00ff00"
|
43
|
+
/\A#?[0-9A-Fa-f]{6}\z/
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_username?
|
47
|
+
# Examples: "john_doe", "user123", "test-user"
|
48
|
+
/\A[a-zA-Z0-9_\-]+\z/
|
49
|
+
end
|
50
|
+
|
51
|
+
def is_decimal?
|
52
|
+
# Examples: "123.45", "0.5", "100"
|
53
|
+
/\A\d+(\.\d+)?\z/
|
54
|
+
end
|
55
|
+
|
56
|
+
def is_integer?
|
57
|
+
# Examples: "123", "-456", "0"
|
58
|
+
/\A-?\d+\z/
|
59
|
+
end
|
60
|
+
|
61
|
+
def is_positive_number?
|
62
|
+
# Examples: "1", "123", "999"
|
63
|
+
/\A[1-9]\d*\z/
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_uuid?
|
67
|
+
# Examples: "550e8400-e29b-41d4-a716-446655440000", "123e4567-e89b-12d3-a456-426614174000"
|
68
|
+
/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i
|
69
|
+
end
|
70
|
+
|
71
|
+
def is_credit_card?
|
72
|
+
# Examples: "1234567812345678", "1234 5678 1234 5678", "1234-5678-1234-5678"
|
73
|
+
/\A\d{4}[\s\-]?\d{4}[\s\-]?\d{4}[\s\-]?\d{4}\z/
|
74
|
+
end
|
75
|
+
|
76
|
+
def is_ssn?
|
77
|
+
# Examples: "123-45-6789", "123456789"
|
78
|
+
/\A\d{3}-?\d{2}-?\d{4}\z/
|
79
|
+
end
|
80
|
+
|
81
|
+
def is_ipv4?
|
82
|
+
# Examples: "192.168.1.1", "10.0.0.255", "8.8.8.8"
|
83
|
+
/\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/
|
84
|
+
end
|
85
|
+
|
86
|
+
def is_time_24h?
|
87
|
+
# Examples: "14:30", "09:45", "23:59"
|
88
|
+
/\A(?:[01]\d|2[0-3]):[0-5]\d\z/
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_date_yyyy_mm_dd?
|
92
|
+
# Examples: "2024-01-15", "2023-12-31", "2022-06-01"
|
93
|
+
/\A\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\z/
|
94
|
+
end
|
95
|
+
|
96
|
+
def has_no_spaces?
|
97
|
+
# Examples: "hello", "test123", "no-spaces-here"
|
98
|
+
/\A[^\s]+\z/
|
99
|
+
end
|
100
|
+
|
101
|
+
def has_no_special_chars?
|
102
|
+
# Examples: "Hello World", "Test 123", "abc"
|
103
|
+
/\A[a-zA-Z0-9\s]+\z/
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Make these methods available at the top level
|
109
|
+
extend NoRegex::PatternMethods
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Custom validators for Rails
|
4
|
+
if defined?(ActiveModel)
|
5
|
+
module NoRegex
|
6
|
+
# Base validator class
|
7
|
+
class BaseValidator < ActiveModel::EachValidator
|
8
|
+
def validate_each(record, attribute, value)
|
9
|
+
return if value.blank? && options[:allow_blank]
|
10
|
+
return if value.nil? && options[:allow_nil]
|
11
|
+
|
12
|
+
unless value.to_s.send(validation_method)
|
13
|
+
record.errors.add(attribute, options[:message] || default_message)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def validation_method
|
20
|
+
raise NotImplementedError
|
21
|
+
end
|
22
|
+
|
23
|
+
def default_message
|
24
|
+
raise NotImplementedError
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Validator for checking if a value contains only numbers
|
29
|
+
class NumberValidator < BaseValidator
|
30
|
+
private
|
31
|
+
def validation_method; :is_number?; end
|
32
|
+
def default_message; "must be a number"; end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Validator for checking if a value contains only letters
|
36
|
+
class LettersValidator < BaseValidator
|
37
|
+
private
|
38
|
+
def validation_method; :is_letters?; end
|
39
|
+
def default_message; "must contain only letters"; end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Validator for checking if a value is alphanumeric
|
43
|
+
class AlphanumericValidator < BaseValidator
|
44
|
+
private
|
45
|
+
def validation_method; :is_alphanumeric?; end
|
46
|
+
def default_message; "must contain only letters and numbers"; end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Validator for email format
|
50
|
+
class EmailFormatValidator < BaseValidator
|
51
|
+
private
|
52
|
+
def validation_method; :is_email?; end
|
53
|
+
def default_message; "must be a valid email address"; end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Validator for URL format
|
57
|
+
class UrlFormatValidator < BaseValidator
|
58
|
+
private
|
59
|
+
def validation_method; :is_url?; end
|
60
|
+
def default_message; "must be a valid URL"; end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Validator for phone number format
|
64
|
+
class PhoneNumberValidator < BaseValidator
|
65
|
+
private
|
66
|
+
def validation_method; :is_phone_number?; end
|
67
|
+
def default_message; "must be a valid phone number"; end
|
68
|
+
end
|
69
|
+
|
70
|
+
# Validator for username format
|
71
|
+
class UsernameValidator < BaseValidator
|
72
|
+
private
|
73
|
+
def validation_method; :is_username?; end
|
74
|
+
def default_message; "can only contain letters, numbers, underscores and hyphens"; end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Extensions to the String class
|
4
|
+
class String
|
5
|
+
# Check methods - return true/false
|
6
|
+
def is_number?
|
7
|
+
match?(/\A\d+\z/)
|
8
|
+
end
|
9
|
+
|
10
|
+
def is_letters?
|
11
|
+
match?(/\A[a-zA-Z]+\z/)
|
12
|
+
end
|
13
|
+
|
14
|
+
def is_alphanumeric?
|
15
|
+
match?(/\A[a-zA-Z0-9]+\z/)
|
16
|
+
end
|
17
|
+
|
18
|
+
def is_email?
|
19
|
+
match?(/\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i)
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_blank?
|
23
|
+
strip.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def is_url?
|
27
|
+
match?(/\A(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?\z/)
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_phone_number?
|
31
|
+
match?(/\A\+?[\d\s\-\(\)]+\z/)
|
32
|
+
end
|
33
|
+
|
34
|
+
def is_zip_code?
|
35
|
+
match?(/\A\d{5}(-\d{4})?\z/)
|
36
|
+
end
|
37
|
+
|
38
|
+
def is_hex_color?
|
39
|
+
match?(/\A#?[0-9A-Fa-f]{6}\z/)
|
40
|
+
end
|
41
|
+
|
42
|
+
def is_username?
|
43
|
+
match?(/\A[a-zA-Z0-9_\-]+\z/)
|
44
|
+
end
|
45
|
+
|
46
|
+
def is_decimal?
|
47
|
+
match?(/\A\d+(\.\d+)?\z/)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_integer?
|
51
|
+
match?(/\A-?\d+\z/)
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_positive_number?
|
55
|
+
match?(/\A[1-9]\d*\z/)
|
56
|
+
end
|
57
|
+
|
58
|
+
def is_uuid?
|
59
|
+
match?(/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/i)
|
60
|
+
end
|
61
|
+
|
62
|
+
def is_credit_card?
|
63
|
+
match?(/\A\d{4}[\s\-]?\d{4}[\s\-]?\d{4}[\s\-]?\d{4}\z/)
|
64
|
+
end
|
65
|
+
|
66
|
+
def is_ssn?
|
67
|
+
match?(/\A\d{3}-?\d{2}-?\d{4}\z/)
|
68
|
+
end
|
69
|
+
|
70
|
+
def is_ipv4?
|
71
|
+
match?(/\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/)
|
72
|
+
end
|
73
|
+
|
74
|
+
def is_time_24h?
|
75
|
+
match?(/\A(?:[01]\d|2[0-3]):[0-5]\d\z/)
|
76
|
+
end
|
77
|
+
|
78
|
+
def is_date_yyyy_mm_dd?
|
79
|
+
match?(/\A\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])\z/)
|
80
|
+
end
|
81
|
+
|
82
|
+
def has_no_spaces?
|
83
|
+
match?(/\A[^\s]+\z/)
|
84
|
+
end
|
85
|
+
|
86
|
+
def has_no_special_chars?
|
87
|
+
match?(/\A[a-zA-Z0-9\s]+\z/)
|
88
|
+
end
|
89
|
+
|
90
|
+
# Manipulation methods - return modified strings
|
91
|
+
def remove_dashes
|
92
|
+
gsub("-", "")
|
93
|
+
end
|
94
|
+
|
95
|
+
def remove_spaces
|
96
|
+
gsub(" ", "")
|
97
|
+
end
|
98
|
+
|
99
|
+
def remove_special_chars
|
100
|
+
gsub(/[^a-zA-Z0-9]/, "")
|
101
|
+
end
|
102
|
+
|
103
|
+
def remove_numbers
|
104
|
+
gsub(/\d/, "")
|
105
|
+
end
|
106
|
+
|
107
|
+
def remove_letters
|
108
|
+
gsub(/[a-zA-Z]/, "")
|
109
|
+
end
|
110
|
+
|
111
|
+
def keep_numbers
|
112
|
+
gsub(/[^\d]/, "")
|
113
|
+
end
|
114
|
+
|
115
|
+
def keep_letters
|
116
|
+
gsub(/[^a-zA-Z]/, "")
|
117
|
+
end
|
118
|
+
|
119
|
+
def to_snake_case
|
120
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
|
121
|
+
.gsub(/([a-z\d])([A-Z])/, '\1_\2')
|
122
|
+
.tr("-", "_")
|
123
|
+
.downcase
|
124
|
+
end
|
125
|
+
|
126
|
+
def to_camel_case
|
127
|
+
parts = split(/[_\-\s]/)
|
128
|
+
parts[0].downcase + parts[1..-1].map(&:capitalize).join
|
129
|
+
end
|
130
|
+
|
131
|
+
# Extraction methods - return arrays or other data
|
132
|
+
def extract_numbers
|
133
|
+
scan(/\d+/)
|
134
|
+
end
|
135
|
+
|
136
|
+
def extract_emails
|
137
|
+
scan(/[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+/i)
|
138
|
+
end
|
139
|
+
|
140
|
+
def word_count
|
141
|
+
split.size
|
142
|
+
end
|
143
|
+
|
144
|
+
def truncate(length = 30, ellipsis = "...")
|
145
|
+
return self if self.length <= length
|
146
|
+
self[0...(length - ellipsis.length)] + ellipsis
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
data/lib/no_regex.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "no_regex/version"
|
4
|
+
require_relative "no_regex/string_extensions"
|
5
|
+
require_relative "no_regex/numeric_extensions"
|
6
|
+
require_relative "no_regex/pattern_methods"
|
7
|
+
|
8
|
+
# Load Rails validators if Rails is present
|
9
|
+
if defined?(Rails) || defined?(ActiveModel)
|
10
|
+
require_relative "no_regex/rails_validators"
|
11
|
+
end
|
12
|
+
|
13
|
+
module NoRegex
|
14
|
+
class Error < StandardError; end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Load aliases after module is defined
|
18
|
+
require_relative "no_regex/aliases"
|
19
|
+
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: no_regex
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Your Name
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: rake
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '13.0'
|
19
|
+
type: :development
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '13.0'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: rspec
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '3.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: rubocop
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '1.21'
|
47
|
+
type: :development
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.21'
|
54
|
+
description: Replace complex regex patterns with simple, readable methods for string
|
55
|
+
validation and manipulation
|
56
|
+
email:
|
57
|
+
- your.email@example.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- README.md
|
63
|
+
- lib/no_regex.rb
|
64
|
+
- lib/no_regex/aliases.rb
|
65
|
+
- lib/no_regex/numeric_extensions.rb
|
66
|
+
- lib/no_regex/pattern_methods.rb
|
67
|
+
- lib/no_regex/rails_validators.rb
|
68
|
+
- lib/no_regex/string_extensions.rb
|
69
|
+
- lib/no_regex/version.rb
|
70
|
+
homepage: https://github.com/yourusername/no_regex
|
71
|
+
licenses:
|
72
|
+
- MIT
|
73
|
+
metadata:
|
74
|
+
homepage_uri: https://github.com/yourusername/no_regex
|
75
|
+
source_code_uri: https://github.com/yourusername/no_regex
|
76
|
+
changelog_uri: https://github.com/yourusername/no_regex/blob/main/CHANGELOG.md
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.6.0
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubygems_version: 3.6.9
|
92
|
+
specification_version: 4
|
93
|
+
summary: Write Ruby without regex
|
94
|
+
test_files: []
|