TextualRegexp 1.8.6
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.
- data/History.txt +5 -0
- data/Manifest.txt +7 -0
- data/README.txt +83 -0
- data/Rakefile +17 -0
- data/bin/texrex +0 -0
- data/lib/texrex.rb +319 -0
- data/test/test_texrex.rb +0 -0
- metadata +63 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
data/README.txt
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
TextualRegexp
|
2
|
+
by Ari Brown and Robert Kremme
|
3
|
+
http://texrex.rubyforge.com
|
4
|
+
|
5
|
+
== DESCRIPTION:
|
6
|
+
|
7
|
+
And english-language wrapper for Regular Expressions - all of a sudden, they seem fun (hopefully)!
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
Incompatible with 1.9, as far as we know. Technically, it supports everything current RegExp does.
|
12
|
+
|
13
|
+
== SYNOPSIS:
|
14
|
+
|
15
|
+
Password = TextualRegexp.new do
|
16
|
+
anchor :beginning
|
17
|
+
|
18
|
+
group :capture do
|
19
|
+
any :letter
|
20
|
+
repeat(4..13) do
|
21
|
+
any :char
|
22
|
+
end
|
23
|
+
any :digit
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
or
|
28
|
+
|
29
|
+
US_Phone = TextualRegexp.new do
|
30
|
+
group :capture do
|
31
|
+
maybe { literal "1"
|
32
|
+
literal "-"
|
33
|
+
}
|
34
|
+
any :of {
|
35
|
+
group { maybe { literal "(" }
|
36
|
+
repeat(3) { any :digit }
|
37
|
+
maybe { literal ")" }
|
38
|
+
}
|
39
|
+
group { repeat(3) { any :digit } }
|
40
|
+
}
|
41
|
+
literal "-"
|
42
|
+
repeat(3) { any :digit }
|
43
|
+
literal "-"
|
44
|
+
repeat(4) { any :digit }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
You can even add them together:
|
49
|
+
a = Password + US_Phone
|
50
|
+
it returns a new TextualRegexp object.
|
51
|
+
|
52
|
+
== REQUIREMENTS:
|
53
|
+
|
54
|
+
Ruby 1.8
|
55
|
+
|
56
|
+
== INSTALL:
|
57
|
+
|
58
|
+
sudo gem install texrex
|
59
|
+
|
60
|
+
== LICENSE:
|
61
|
+
|
62
|
+
(The MIT License)
|
63
|
+
|
64
|
+
Copyright (c) 2007
|
65
|
+
|
66
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
67
|
+
a copy of this software and associated documentation files (the
|
68
|
+
'Software'), to deal in the Software without restriction, including
|
69
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
70
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
71
|
+
permit persons to whom the Software is furnished to do so, subject to
|
72
|
+
the following conditions:
|
73
|
+
|
74
|
+
The above copyright notice and this permission notice shall be
|
75
|
+
included in all copies or substantial portions of the Software.
|
76
|
+
|
77
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
78
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
79
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
80
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
81
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
82
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
83
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- ruby -*-
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'hoe'
|
5
|
+
require './lib/texrex.rb'
|
6
|
+
|
7
|
+
Hoe.new('TextualRegexp', TextualRegexp::VERSION) do |p|
|
8
|
+
p.rubyforge_name = 'texrex'
|
9
|
+
p.author = 'Ari Brown and Robert Kremme'
|
10
|
+
p.email = 'ari [at] aribrown.com'
|
11
|
+
p.summary = 'An english wrapper for Regular Expressions'
|
12
|
+
p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
13
|
+
p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
14
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
15
|
+
end
|
16
|
+
|
17
|
+
# vim: syntax=Ruby
|
data/bin/texrex
ADDED
File without changes
|
data/lib/texrex.rb
ADDED
@@ -0,0 +1,319 @@
|
|
1
|
+
#!ruby
|
2
|
+
|
3
|
+
# Written by Robert Klemme and (a little) Ari Brown
|
4
|
+
|
5
|
+
class TextualRegexp
|
6
|
+
|
7
|
+
attr_reader :block
|
8
|
+
|
9
|
+
def initialize(flags = 0, &b)
|
10
|
+
@buffer = ""
|
11
|
+
@flags = flags
|
12
|
+
@groups = 0
|
13
|
+
|
14
|
+
if b
|
15
|
+
@block = b
|
16
|
+
instance_eval(&b)
|
17
|
+
finish
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# construction
|
22
|
+
|
23
|
+
=begin
|
24
|
+
Include another TextualRegexp's code
|
25
|
+
=end
|
26
|
+
def include(something)
|
27
|
+
instance_eval(something.block)
|
28
|
+
end
|
29
|
+
|
30
|
+
=begin RDoc
|
31
|
+
TextualRegexp.new + Regexp.new
|
32
|
+
TextualRegexp.new + TextualRegexp.new
|
33
|
+
=end
|
34
|
+
def +(other)
|
35
|
+
if other.is_a?(Regexp)
|
36
|
+
g = self.rx
|
37
|
+
h = Regexp.new(g.source + other.source)
|
38
|
+
elsif other.is_a?(TextualRegexp)
|
39
|
+
self + other.rx
|
40
|
+
else
|
41
|
+
raise "Invalid Usage"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
=begin RDoc
|
46
|
+
Matches a literal string.
|
47
|
+
=end
|
48
|
+
def text(s)
|
49
|
+
update do
|
50
|
+
@buffer << Regexp.escape(s)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def regexp(s)
|
55
|
+
update do
|
56
|
+
@buffer << s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
alias literal text
|
61
|
+
|
62
|
+
def case_insensitive(&b)
|
63
|
+
update do
|
64
|
+
@buffer << "(?i:"
|
65
|
+
instance_eval(&b)
|
66
|
+
@buffer << ")"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def case_sensitive(&b)
|
71
|
+
update do
|
72
|
+
@buffer << "(?-i:"
|
73
|
+
instance_eval(&b)
|
74
|
+
@buffer << ")"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
=begin RDoc
|
79
|
+
Sets a group that gets captured
|
80
|
+
=end
|
81
|
+
def group(mode=:non_capturing, &b)
|
82
|
+
update do
|
83
|
+
@buffer << "("
|
84
|
+
if mode == :capturing || mode == :capture
|
85
|
+
@groups += 1
|
86
|
+
else
|
87
|
+
@buffer << "?:"
|
88
|
+
end
|
89
|
+
instance_eval(&b)
|
90
|
+
@buffer << ")"
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
=begin RDoc
|
95
|
+
If a string is given, it's the equivalent of [sample].
|
96
|
+
If an array is given, it will match any one of the fields in the array.
|
97
|
+
If sample is nil, EXPLANATION
|
98
|
+
=end
|
99
|
+
def any(sample=nil, mode=:are, &b)
|
100
|
+
update do
|
101
|
+
sample = ("\w\\" + Regexp.escape("'_/;:-!@*()")) if sample == :char
|
102
|
+
sample = "0-9" if sample == :digit
|
103
|
+
sample = "a-zA-Z" if sample == :letter
|
104
|
+
case sample
|
105
|
+
when String
|
106
|
+
@buffer << "["
|
107
|
+
@buffer << "^" if mode == :not
|
108
|
+
@buffer << sample << "]"
|
109
|
+
when Array
|
110
|
+
@buffer << "(?:"
|
111
|
+
@buffer << "^" if mode == :not
|
112
|
+
@buffer << sample.join("|") << ")"
|
113
|
+
when nil, :of
|
114
|
+
@buffer << "(?:"
|
115
|
+
@buffer << "^" if mode == :not
|
116
|
+
@buffer << TxCollector.new(b).raw_rx << ")"
|
117
|
+
else
|
118
|
+
raise "Wrong usage"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
=begin RDoc
|
124
|
+
If mode is set to :non_greedy (default), the block will match at least once. BETTER EXPLANATION NEEDED
|
125
|
+
=end
|
126
|
+
def at_least_once(mode = :non_greedy, &b)
|
127
|
+
update do
|
128
|
+
instance_eval(&b)
|
129
|
+
@buffer << "+"
|
130
|
+
@buffer << "?" unless mode == :greedy
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
=begin RDoc
|
135
|
+
If mode is set to :non_greedy (default), the block will match at least zero times. BETTER EXPLANATION NEEDED
|
136
|
+
=end
|
137
|
+
def at_least_zero(mode = :non_greedy, &b)
|
138
|
+
update do
|
139
|
+
instance_eval(&b)
|
140
|
+
@buffer << "*"
|
141
|
+
@buffer << "?" unless mode == :greedy
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
=begin RDoc
|
146
|
+
The block will match either once or not at all (equivalent of '?')
|
147
|
+
=end
|
148
|
+
def maybe(&b)
|
149
|
+
update do
|
150
|
+
instance_eval(&b)
|
151
|
+
@buffer << "?"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
=begin RDoc
|
156
|
+
Repeats the block either spec times, or, if given a range (1..4), at least 1 and at most 4
|
157
|
+
=end
|
158
|
+
def repeat(spec, &b)
|
159
|
+
update do
|
160
|
+
case spec
|
161
|
+
when 0
|
162
|
+
# ignore
|
163
|
+
when 1
|
164
|
+
# just once
|
165
|
+
instance_eval(&b)
|
166
|
+
when Integer
|
167
|
+
raise "Illegal negative" if spec < 0
|
168
|
+
instance_eval(&b)
|
169
|
+
@buffer << "{" << spec.to_s << "}"
|
170
|
+
when Range
|
171
|
+
instance_eval(&b)
|
172
|
+
@buffer << "{" << spec.first.to_s << ","
|
173
|
+
@buffer << (spec.exclude_end? ? spec.last.pred : spec.last).to_s
|
174
|
+
@buffer << "}"
|
175
|
+
else
|
176
|
+
raise "Wrong usage"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
=begin RDoc
|
182
|
+
Sets an anchor to :beginning (\\A), :end (\\z), :word (\\b), or :eol and :end_of_line ($)
|
183
|
+
=end
|
184
|
+
def anchor(where)
|
185
|
+
update do
|
186
|
+
@buffer << case where
|
187
|
+
when :beginning
|
188
|
+
"\\A"
|
189
|
+
when :end
|
190
|
+
"\\z"
|
191
|
+
when :word
|
192
|
+
"\\b"
|
193
|
+
when :eol, :end_of_line
|
194
|
+
"$"
|
195
|
+
else
|
196
|
+
raise "Illegal anchor #{where}"
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def finish
|
202
|
+
@buffer.freeze
|
203
|
+
@rx = Regexp.new(@buffer, @flags)
|
204
|
+
freeze
|
205
|
+
end
|
206
|
+
|
207
|
+
# usage
|
208
|
+
|
209
|
+
=begin RDoc
|
210
|
+
Returns the equivalent RegExp object
|
211
|
+
=end
|
212
|
+
def rx; @rx end
|
213
|
+
|
214
|
+
def groups; @groups end
|
215
|
+
|
216
|
+
=begin RDoc
|
217
|
+
Returns the raw RegExp code as a string
|
218
|
+
=end
|
219
|
+
def raw_rx
|
220
|
+
@buffer
|
221
|
+
end
|
222
|
+
|
223
|
+
def to_s
|
224
|
+
rx.to_s
|
225
|
+
end
|
226
|
+
|
227
|
+
=begin RDoc
|
228
|
+
Scans self to s, and returns the matches made
|
229
|
+
=end
|
230
|
+
def scan(s, &b)
|
231
|
+
s.scan(rx, &b)
|
232
|
+
end
|
233
|
+
|
234
|
+
def split(s, &b)
|
235
|
+
s.split(rx, &b)
|
236
|
+
end
|
237
|
+
|
238
|
+
=begin RDoc
|
239
|
+
Matches self to s, returns the match if true, and false if false
|
240
|
+
=end
|
241
|
+
def =~(s)
|
242
|
+
case s
|
243
|
+
when TextualRegexp
|
244
|
+
s.rx.match(self)
|
245
|
+
else
|
246
|
+
self.rx.match(s)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
=begin RDoc
|
251
|
+
Matches self to s, returns true and false
|
252
|
+
=end
|
253
|
+
def ===(s)
|
254
|
+
return true if self =~ s
|
255
|
+
return false
|
256
|
+
end
|
257
|
+
|
258
|
+
=begin RDoc
|
259
|
+
Captures all of the captured matches, which are accesible by their names
|
260
|
+
=end
|
261
|
+
|
262
|
+
private
|
263
|
+
def update
|
264
|
+
raise "Immutable" if frozen?
|
265
|
+
yield
|
266
|
+
self
|
267
|
+
end
|
268
|
+
|
269
|
+
def collect_rx(b)
|
270
|
+
TxCollector.new(b).raw_rx
|
271
|
+
end
|
272
|
+
|
273
|
+
class TxCollector
|
274
|
+
def initialize(b)
|
275
|
+
@rx = []
|
276
|
+
instance_eval(&b)
|
277
|
+
end
|
278
|
+
|
279
|
+
def method_missing(*a,&b)
|
280
|
+
trx = TextualRegexp.new
|
281
|
+
trx.send(*a,&b)
|
282
|
+
@rx << trx
|
283
|
+
self
|
284
|
+
end
|
285
|
+
|
286
|
+
def raw_rx
|
287
|
+
@rx.map {|rx| rx.raw_rx}.join("|")
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
# simple test
|
293
|
+
=begin
|
294
|
+
mail_addr = TextualRegexp.new do
|
295
|
+
anchor :beginning
|
296
|
+
|
297
|
+
group :capture do
|
298
|
+
at_least_once { any "a-z" + "0-9" + "_" }
|
299
|
+
end
|
300
|
+
|
301
|
+
literal "@"
|
302
|
+
|
303
|
+
group :capture do
|
304
|
+
repeat 1..4 do
|
305
|
+
at_least_once { any "a-z" + "0-9" + "_" }
|
306
|
+
literal "."
|
307
|
+
end
|
308
|
+
any %w{com edu org}
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
puts mail_addr, mail_addr.rx, mail_addr.raw_rx
|
313
|
+
puts
|
314
|
+
puts mail_addr, mail_addr.raw_rx, mail_addr.rx.class
|
315
|
+
|
316
|
+
mail_addr.scan "foobar@google.com" do |m|
|
317
|
+
p m
|
318
|
+
end
|
319
|
+
=end
|
data/test/test_texrex.rb
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.4
|
3
|
+
specification_version: 1
|
4
|
+
name: TextualRegexp
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 1.8.6
|
7
|
+
date: 2007-09-06 00:00:00 -04:00
|
8
|
+
summary: An english wrapper for Regular Expressions
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: ari [at] aribrown.com
|
12
|
+
homepage: " by Ari Brown and Robert Kremme"
|
13
|
+
rubyforge_project: texrex
|
14
|
+
description: "== FEATURES/PROBLEMS: Incompatible with 1.9, as far as we know. Technically, it supports everything current RegExp does. == SYNOPSIS: Password = TextualRegexp.new do anchor :beginning group :capture do any :letter repeat(4..13) do any :char end any :digit end end"
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Ari Brown and Robert Kremme
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- Rakefile
|
36
|
+
- bin/texrex
|
37
|
+
- lib/texrex.rb
|
38
|
+
- test/test_texrex.rb
|
39
|
+
test_files:
|
40
|
+
- test/test_texrex.rb
|
41
|
+
rdoc_options:
|
42
|
+
- --main
|
43
|
+
- README.txt
|
44
|
+
extra_rdoc_files:
|
45
|
+
- History.txt
|
46
|
+
- Manifest.txt
|
47
|
+
- README.txt
|
48
|
+
executables:
|
49
|
+
- texrex
|
50
|
+
extensions: []
|
51
|
+
|
52
|
+
requirements: []
|
53
|
+
|
54
|
+
dependencies:
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: hoe
|
57
|
+
version_requirement:
|
58
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.3.0
|
63
|
+
version:
|