verbal 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 526bba90d57ec2d0d460252bee24f7068b531f39
4
- data.tar.gz: 53190021c432f71d10c9f9f50e80176d20bedf42
3
+ metadata.gz: be46d2de1760f8493f75fdde627b054376a2409c
4
+ data.tar.gz: 3a1e75bb4a2cda4f31134ac0021e7677c421b8cc
5
5
  SHA512:
6
- metadata.gz: d8fe772702fed5ec96203b6bcdcad4e46c9d1d7c8c898fd0d9a76cfd22f5608ac983f0381b17cd1951e0e27d9062576b44af64939050af70dd42feed047ed2ce
7
- data.tar.gz: b2ff2540cdb9dc558d539b2a04a403ddcf028e4b3e92db27005e5bddbed83c6be144f9e48a32f491c9847172a8da24dff82eef5a771aa9ba2857421c414b348e
6
+ metadata.gz: 8000d9253dd50b1a40cbad16284f1ceb1646a200e36bda1550bfdaf0839f50659de938d21228d56c98f531d2cec2a3d5cea78aa0b3aff26c7f859dd5dadb9d00
7
+ data.tar.gz: fce342144f71b2725d898bb36b092e74bc94a6ed309dff8625748c58d166c8df43002e66b4eef3dcc0aef9a9ae6a7739657823ed73d0b281d75d7dd6f27cedc5
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  Verbal
2
2
  =====================
3
3
  [![Build Status](https://travis-ci.org/jimjh/verbal.png?branch=master)](https://travis-ci.org/jimjh/verbal)
4
+ [![Gem Version](https://badge.fury.io/rb/verbal.png)](http://badge.fury.io/rb/verbal)
4
5
 
5
6
  ## Overview
6
7
  Verbal is a Ruby library that helps to construct difficult regular expressions.
7
8
  It's ported from the awesome JavaScript [VerbalExpressions](https://github.com/jehna/VerbalExpressions).
9
+ Detailed documentation is available at [rubydoc](http://rubydoc.info/gems/verbal/frames).
8
10
 
9
11
  ## Installation
10
12
 
@@ -60,6 +62,21 @@ result = replace_me.gsub( expression, "duck" );
60
62
  puts result # Outputs "Replace duck with a duck"
61
63
  ```
62
64
 
65
+ ### Capturing strings
66
+
67
+ ```ruby
68
+ # create expression
69
+ verbal = Verbal.new do
70
+ capture { anything }
71
+ find /\sby\s/
72
+ capture { anything }
73
+ end
74
+ # match against test string
75
+ data = verbal.match('this is it by michael jackson')
76
+ puts data[1] # >> 'this is it'
77
+ puts data[2] # >> 'michael jackson'
78
+ ```
79
+
63
80
  ## Issues
64
81
  - I haven't yet ported the modifier code because Ruby Regexp handles modifiers a little differently.
65
82
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -5,16 +5,16 @@
5
5
  class Verbal < Regexp
6
6
 
7
7
  # @example Create a new RegExp
8
- # verbal = Verbal.new do
9
- # start_of_line
10
- # find 'x'
11
- # end
12
- # verbal =~ 'x' # => 0
8
+ # verbal = Verbal.new do
9
+ # start_of_line
10
+ # find 'x'
11
+ # end
12
+ # verbal =~ 'x' # => 0
13
13
  def initialize(&block)
14
- @prefixes = ""
15
- @source = ""
16
- @suffixes = ""
17
- @modifiers = "" # TODO: Ruby Regexp option flags
14
+ @prefixes = ''
15
+ @source = ''
16
+ @suffixes = ''
17
+ @modifiers = '' # TODO: Ruby Regexp option flags
18
18
  instance_eval(&block)
19
19
  super(@prefixes + @source + @suffixes, @modifiers)
20
20
  end
@@ -53,6 +53,32 @@ class Verbal < Regexp
53
53
  @suffixes = '$'
54
54
  end
55
55
 
56
+ # Marks the expression to start at the beginning of the string.
57
+ # @example Matching the entire string
58
+ # verbal = Verbal.new do
59
+ # start_of_string
60
+ # find 'dinosaur'
61
+ # end_of_string
62
+ # end
63
+ # verbal.match('dinosaur') # matches
64
+ # verbal.match('a dinosaur') # does not match
65
+ def start_of_string
66
+ @prefixes = '\A' + @prefixes
67
+ end
68
+
69
+ # Marks the expression to start at the end of the string.
70
+ # @example Matching the entire string
71
+ # verbal = Verbal.new do
72
+ # start_of_string
73
+ # find 'dinosaur'
74
+ # end_of_string
75
+ # end
76
+ # verbal.match('dinosaur') # matches
77
+ # verbal.match('dinosaurs') # does not match
78
+ def end_of_string
79
+ @suffixes += '\z'
80
+ end
81
+
56
82
  # Add a string to the expression that might appear once.
57
83
  # @param [String] value the string to look for
58
84
  # @example Find http or https.
@@ -61,7 +87,7 @@ class Verbal < Regexp
61
87
  # maybe 's'
62
88
  # end
63
89
  def maybe(value)
64
- append "(#{sanitize value})?"
90
+ append "(?:#{sanitize value})?"
65
91
  end
66
92
 
67
93
  # Matches any character any number of times.
@@ -70,7 +96,7 @@ class Verbal < Regexp
70
96
  # anything
71
97
  # end
72
98
  def anything
73
- append '(.*)'
99
+ append '(?:.*)'
74
100
  end
75
101
 
76
102
  # Matches any number of any character that is not in +value+.
@@ -80,7 +106,7 @@ class Verbal < Regexp
80
106
  # end
81
107
  # @param [String] value characters to excluded
82
108
  def anything_but(value)
83
- append "([^#{sanitize value}]*)"
109
+ append "(?:[^#{sanitize value}]*)"
84
110
  end
85
111
 
86
112
  # Adds a universal line break expression.
@@ -91,7 +117,7 @@ class Verbal < Regexp
91
117
  # end
92
118
  # lorem.gsub(veral, "<br>\n") # => "Lorem.<br>\nDolor<br>\namet."
93
119
  def line_break
94
- append '(\n|(\r\n))'
120
+ append '(?:\n|(?:\r\n))'
95
121
  end
96
122
  alias_method :br, :line_break
97
123
 
@@ -139,13 +165,19 @@ class Verbal < Regexp
139
165
  append value
140
166
  end
141
167
 
142
- # Matches multiple of +value+. Defaults to one or many. You can specify zero
143
- # or more by suffixing +value+ with +'*'+.
144
- # @param [String] value string to match
168
+ # Matches one or many of value.
169
+ # @param [String|Regexp] value string to match
170
+ # @example Matching multiples of "xyz"
171
+ # verbal = Verbal.new { multiple 'xyz' }
172
+ # verbal.match('this is xyzxyz')[0] # => 'xyzxyz'
173
+ # @example Matching multiples of /[xyz]/
174
+ # verbal = Verbal.new { multiple /[xyz]/ }
175
+ # verbal.match('abcxxyz')[0] # => 'xxyz'
145
176
  def multiple(value)
146
- value = sanitize value
147
- value += '+' unless %w[+ *].include? value[-1]
148
- append value
177
+ append case value
178
+ when Regexp then "(#{value.source})+"
179
+ else "(#{sanitize value})+"
180
+ end
149
181
  end
150
182
 
151
183
  # Adds a alternative expression to be matched.
@@ -160,12 +192,26 @@ class Verbal < Regexp
160
192
  # end
161
193
  # link =~ verbal # => 0
162
194
  def otherwise(value = nil)
163
- @prefixes += "(" unless @prefixes.include?("(")
164
- @suffixes = ")" + @suffixes unless @suffixes.include?(")")
165
- append(")|(")
195
+ @prefixes += "(?:"
196
+ @suffixes = ")" + @suffixes
197
+ append(")|(?:")
166
198
  find(value) if value
167
199
  end
168
200
 
201
+ # Captures the nested regular expression.
202
+ # @example Capture the title of the concert and performer
203
+ # verbal = Verbal.new do
204
+ # capture { anything }
205
+ # find /\sby\s/
206
+ # capture { anything }
207
+ # end
208
+ # data = verbal.match('this is it by michael jackson')
209
+ # data[1] # => 'this is it'
210
+ # data[2] # => 'michael jackson'
211
+ def capture(&block)
212
+ append "(#{Verbal.new(&block).source})"
213
+ end
214
+
169
215
  private
170
216
 
171
217
  # Escapes +value+ so that it can be used in a regular expression.
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#anythingBut' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'http'
10
+ anything_but 's:.?'
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '(?:http)(?:[^s:\.\?]*)' }
15
+
16
+ it 'matches a string without a suffix' do
17
+ (verbal =~ 'http').should eq 0
18
+ end
19
+
20
+ it 'matches a string with a suffix' do
21
+ verbal.match('whttps://')[0].should eq 'http'
22
+ end
23
+
24
+ end
25
+
26
+
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#anything' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'http'
10
+ anything
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '(?:http)(?:.*)' }
15
+
16
+ it 'matches a string without a suffix' do
17
+ (verbal =~ 'http').should eq 0
18
+ end
19
+
20
+ it 'matches a string with a suffix' do
21
+ verbal.match('whttps://')[0].should eq 'https://'
22
+ end
23
+
24
+ end
25
+
26
+
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#capture' do
4
+
5
+ subject { verbal }
6
+ let(:verbal) do
7
+ Verbal.new do
8
+ capture { anything }
9
+ find ' by '
10
+ capture { anything }
11
+ end
12
+ end
13
+ let(:string) { 'this is it by michael jackson' }
14
+
15
+ it { should match string }
16
+
17
+ context 'matched data' do
18
+ subject { verbal.match string }
19
+ its([1]) { should eq 'this is it' }
20
+ its([2]) { should eq 'michael jackson' }
21
+ end
22
+
23
+ end
24
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#end_of_line' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'x'
10
+ end_of_line
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '(?:x)$' }
15
+
16
+ it 'matches a string at the end of a line' do
17
+ (verbal =~ 'zyx').should eq 2
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#end_of_string' do
4
+
5
+ subject { verbal }
6
+ let(:verbal) do
7
+ Verbal.new do
8
+ find 'cat'
9
+ end_of_string
10
+ end
11
+ end
12
+
13
+ its(:source) { should eq '(?:cat)\z' }
14
+ it { should match 'cat' }
15
+ it { should_not match 'cats' }
16
+
17
+ end
18
+
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#find' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'lions? yup.'
10
+ end
11
+ end
12
+
13
+ its(:source) { should eq '(?:lions\?\ yup\.)' }
14
+
15
+ it 'matches a string at the correct position' do
16
+ (verbal =~ 'are these lions? yup...').should eq 10
17
+ end
18
+
19
+ end
20
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#line_break' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'this'
10
+ line_break
11
+ find 'that'
12
+ end
13
+ end
14
+
15
+ its(:source) { should eq '(?:this)(?:\n|(?:\r\n))(?:that)' }
16
+
17
+ it 'matches a string correctly' do
18
+ verbal.match("this\nthat and w")[0].should eq "this\nthat"
19
+ end
20
+
21
+ end
22
+
23
+
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#maybe' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ find 'http'
10
+ maybe 's'
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '(?:http)(?:s)?' }
15
+
16
+ it 'matches a string without the value' do
17
+ (verbal =~ 'http').should eq 0
18
+ end
19
+
20
+ it 'matches a string with the value' do
21
+ (verbal =~ 'https').should eq 0
22
+ end
23
+
24
+ end
25
+
@@ -0,0 +1,26 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#multiple' do
4
+
5
+ subject { verbal }
6
+
7
+ context 'string' do
8
+ let(:verbal) { Verbal.new { multiple 'zk.+' } }
9
+ its(:source) { should eq '(zk\.\+)+' }
10
+ it 'matches multiples of the given value' do
11
+ (verbal =~ 'whereiszk.+zk.+zk.+qw').should eq 7
12
+ end
13
+ end
14
+
15
+ context 'regex' do
16
+ let(:verbal) { Verbal.new { multiple(/[xyz]u/) } }
17
+ its(:source) { should eq '([xyz]u)+' }
18
+ it 'matches multiples of the given value' do
19
+ verbal.match('this is xuxuyuzu')[0].should eq 'xuxuyuzu'
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+
26
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#otherwise' do
4
+
5
+ subject { verbal }
6
+ let(:verbal) do
7
+ Verbal.new do
8
+ find 'http'
9
+ maybe 's'
10
+ find '://'
11
+ otherwise
12
+ maybe 's'
13
+ find 'ftp://'
14
+ end
15
+ end
16
+
17
+ it { should match 'http://' }
18
+ it { should match 'https://' }
19
+ it { should match 'ftp://' }
20
+ it { should match 'sftp://' }
21
+
22
+ end
23
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#range' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ range 'a', 'z', '0', '9'
10
+ find 'that'
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '[a-z0-9](?:that)' }
15
+
16
+ it 'matches a string correctly' do
17
+ (verbal =~ 'W9that').should eq 1
18
+ end
19
+
20
+ end
21
+
22
+
23
+
@@ -0,0 +1,21 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#start_of_line' do
4
+
5
+ subject { verbal }
6
+
7
+ let(:verbal) do
8
+ Verbal.new do
9
+ start_of_line
10
+ find 'x'
11
+ end
12
+ end
13
+
14
+ its(:source) { should eq '^(?:x)' }
15
+
16
+ it 'matches a string at the beginning' do
17
+ (verbal =~ 'xyz').should eq 0
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe Verbal, '#start_of_string' do
4
+
5
+ subject { verbal }
6
+ let(:verbal) do
7
+ Verbal.new do
8
+ start_of_string
9
+ find 'cat'
10
+ end
11
+ end
12
+
13
+ its(:source) { should eq '\A(?:cat)' }
14
+ it { should match 'cat' }
15
+ it { should_not match 'a cat' }
16
+
17
+ end
18
+
@@ -2,31 +2,6 @@ require 'spec_helper'
2
2
 
3
3
  describe Verbal do
4
4
 
5
- describe '#find' do
6
-
7
- let(:matcher) do
8
- Verbal.new do
9
- find 'lions'
10
- end
11
- end
12
-
13
- it 'should correctly build find regex' do
14
- matcher.source.should == '(?:lions)'
15
- end
16
-
17
- it 'should correctly match find' do
18
- matcher.match('lions').should be_true
19
- end
20
-
21
- it 'should match part of a string with find' do
22
- matcher.match('lions, tigers, and bears, oh my!').should be_true
23
- end
24
-
25
- it 'should only match the `find` part of a string' do
26
- matcher.match('lions, tigers, and bears, oh my!')[0].should == 'lions'
27
- end
28
- end
29
-
30
5
  describe 'URL Regex Test' do
31
6
 
32
7
  let(:matcher) do
@@ -42,7 +17,7 @@ describe Verbal do
42
17
  end
43
18
 
44
19
  it 'successfully builds regex for matching URLs' do
45
- matcher.source.should == "^(?:http)(s)?(?:://)(www\\.)?([^\\ ]*)$"
20
+ matcher.source.should == "^(?:http)(?:s)?(?:://)(?:www\\.)?(?:[^\\ ]*)$"
46
21
  end
47
22
 
48
23
  it 'matches regular http URL' do
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "verbal"
8
- s.version = "0.1.1"
8
+ s.version = "0.1.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Ryan Endacott", "Jim Lim"]
12
- s.date = "2013-07-25"
12
+ s.date = "2013-07-26"
13
13
  s.description = "Verbal Expressions is a library that makes constructing difficult regular expressions simple and easy!"
14
14
  s.email = "jim@jimjh.com"
15
15
  s.extra_rdoc_files = [
@@ -27,7 +27,20 @@ Gem::Specification.new do |s|
27
27
  "Rakefile",
28
28
  "VERSION",
29
29
  "lib/verbal.rb",
30
+ "spec/anything_but_spec.rb",
31
+ "spec/anything_spec.rb",
32
+ "spec/capture_spec.rb",
33
+ "spec/end_of_line_spec.rb",
34
+ "spec/end_of_string_spec.rb",
35
+ "spec/find_spec.rb",
36
+ "spec/line_break_spec.rb",
37
+ "spec/maybe_spec.rb",
38
+ "spec/multiple_spec.rb",
39
+ "spec/otherwise_spec.rb",
40
+ "spec/range_spec.rb",
30
41
  "spec/spec_helper.rb",
42
+ "spec/start_of_line_spec.rb",
43
+ "spec/start_of_string_spec.rb",
31
44
  "spec/verbal_spec.rb",
32
45
  "verbal.gemspec"
33
46
  ]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: verbal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Endacott
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-25 00:00:00.000000000 Z
12
+ date: 2013-07-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -86,7 +86,20 @@ files:
86
86
  - Rakefile
87
87
  - VERSION
88
88
  - lib/verbal.rb
89
+ - spec/anything_but_spec.rb
90
+ - spec/anything_spec.rb
91
+ - spec/capture_spec.rb
92
+ - spec/end_of_line_spec.rb
93
+ - spec/end_of_string_spec.rb
94
+ - spec/find_spec.rb
95
+ - spec/line_break_spec.rb
96
+ - spec/maybe_spec.rb
97
+ - spec/multiple_spec.rb
98
+ - spec/otherwise_spec.rb
99
+ - spec/range_spec.rb
89
100
  - spec/spec_helper.rb
101
+ - spec/start_of_line_spec.rb
102
+ - spec/start_of_string_spec.rb
90
103
  - spec/verbal_spec.rb
91
104
  - verbal.gemspec
92
105
  homepage: http://github.com/jimjh/verbal