mail_address 0.0.1
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/.gitignore +14 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +5 -0
- data/lib/mail_address/address.rb +118 -0
- data/lib/mail_address/mail_address.rb +115 -0
- data/lib/mail_address/version.rb +3 -0
- data/lib/mail_address.rb +6 -0
- data/mail_address.gemspec +24 -0
- data/spec/mail_address_spec.rb +184 -0
- data/spec/spec_helper.rb +3 -0
- metadata +108 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 9035be90e1060e267fc1a4f0279822c6b1633d84
|
|
4
|
+
data.tar.gz: e3bd93412deb9a74d5ba6373a8907fc92f57096f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d180e4d471c3546dfb981d1e1c18ea3405c580742ba3b6a3177babab8ea156299ed1a21856c40627d3ec6bbb499978a847f51a169ec3c97838b83b798471e62e
|
|
7
|
+
data.tar.gz: ca3c43c60d7394925718504559243fdd7ca30678ba56735f73ef56b587db70c6d68d05f75ca7cf4b4fd9f2274f2f27690225c889931795e1e733c87a6c728793
|
data/.gitignore
ADDED
data/.rspec
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
--color
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2014 Kizashi Nagata
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# MailAddress [](https://travis-ci.org/kizashi1122/mail_address)
|
|
2
|
+
|
|
3
|
+
MailAddress is a simple email address parser.
|
|
4
|
+
This library is implemented based on Perl Module Mail::Address.
|
|
5
|
+
|
|
6
|
+
[mail](https://github.com/mikel/mail) is a great gem library. But some email addresses (mostly are violated RFC) are unparsable with mail gem which is strictly RFC compliant. In perl, [Mail::Address](http://search.cpan.org/~markov/MailTools-2.14/lib/Mail/Address.pod) is a very common library to parse email address. Mail::Address conviniently can parse even RFC-violated email addresses such as:
|
|
7
|
+
|
|
8
|
+
```rb
|
|
9
|
+
# mail gem cannot parse the following addresses
|
|
10
|
+
Ello [Do Not Reply] <do-not-reply@ello.co> # [, ] are not permitted according to RFC5322
|
|
11
|
+
大阪 太郎<osaka@example.com> # no whitespace just before <
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
So I straightforwardly converted Perl module Mail::Address to Ruby gem.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
Add this line to your application's Gemfile:
|
|
19
|
+
|
|
20
|
+
```ruby
|
|
21
|
+
gem 'mail_address'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
And then execute:
|
|
25
|
+
|
|
26
|
+
$ bundle
|
|
27
|
+
|
|
28
|
+
Or install it yourself as:
|
|
29
|
+
|
|
30
|
+
$ gem install mail_address
|
|
31
|
+
|
|
32
|
+
## Usage
|
|
33
|
+
|
|
34
|
+
It's almost the same as Mail::Address(Perl).
|
|
35
|
+
|
|
36
|
+
```rb
|
|
37
|
+
require 'mail_address'
|
|
38
|
+
|
|
39
|
+
addrs = MailAddress.parse(line)
|
|
40
|
+
|
|
41
|
+
addrs.each do |addr|
|
|
42
|
+
p addr.format
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Contributing
|
|
47
|
+
|
|
48
|
+
1. Fork it ( https://github.com/[my-github-username]/mail_address/fork )
|
|
49
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
|
50
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
|
51
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
|
52
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
module MailAddress
|
|
2
|
+
|
|
3
|
+
class Address
|
|
4
|
+
|
|
5
|
+
def initialize(phrase, address, comment)
|
|
6
|
+
@phrase = phrase
|
|
7
|
+
@address = address
|
|
8
|
+
@comment = comment
|
|
9
|
+
end
|
|
10
|
+
attr_accessor :phrase, :address, :comment
|
|
11
|
+
|
|
12
|
+
ATEXT = '[\-\w !#$%&\'*+/=?^`{|}~]'
|
|
13
|
+
|
|
14
|
+
def format
|
|
15
|
+
addr = []
|
|
16
|
+
if !@phrase.nil? && @phrase.length > 0 then
|
|
17
|
+
addr.push(
|
|
18
|
+
@phrase.match(/^(?:\s*#{ATEXT}\s*)+$/) ? @phrase
|
|
19
|
+
: @phrase.match(/(?<!\\)"/) ? @phrase
|
|
20
|
+
: %Q("#{@phrase}")
|
|
21
|
+
)
|
|
22
|
+
addr.push "<#{@address}>" if !@address.nil? && @address.length > 0
|
|
23
|
+
elsif !@address.nil? && @address.length > 0 then
|
|
24
|
+
addr.push(@address)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if (!@comment.nil? && @comment.match(/\S/)) then
|
|
28
|
+
@comment.sub!(/^\s*\(?/, '(')
|
|
29
|
+
@comment.sub!(/\)?\s*$/, ')')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
addr.push(@comment) if !@comment.nil? && @comment.length > 0
|
|
33
|
+
addr.join(' ')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def name
|
|
37
|
+
phrase = @phrase
|
|
38
|
+
addr = @address
|
|
39
|
+
|
|
40
|
+
phrase = @comment unless !phrase.nil? && phrase.length > 0
|
|
41
|
+
|
|
42
|
+
name = Address._extract_name(phrase)
|
|
43
|
+
|
|
44
|
+
# first.last@domain address
|
|
45
|
+
if (name == '') && (md = addr.match(/([^\%\.\@_]+([\._][^\%\.\@_]+)+)[\@\%]/)) then
|
|
46
|
+
name = md[1]
|
|
47
|
+
name.gsub!(/[\._]+/, ' ')
|
|
48
|
+
name = Address._extract_name name
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if (name == '' && addr.match(%r{/g=}i)) then # X400 style address
|
|
52
|
+
f = addr.match(%r{g=([^/]*)}i)
|
|
53
|
+
l = addr.match(%r{s=([^/]*)}i)
|
|
54
|
+
name = Address._extract_name "#{f[1]} #{l[1]}"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
name.length > 0 ? name : nil
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def host
|
|
61
|
+
addr = @address || '';
|
|
62
|
+
i = addr.rindex('@')
|
|
63
|
+
i >= 0 ? addr[i + 1 .. -1] : nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def user
|
|
68
|
+
addr = @address || '';
|
|
69
|
+
i = addr.rindex('@')
|
|
70
|
+
i >= 0 ? addr[0 ... i] : addr
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
# given a comment, attempt to extract a person's name
|
|
76
|
+
def self._extract_name(name)
|
|
77
|
+
# This function can be called as method as well
|
|
78
|
+
return '' if name.nil? || name == ''
|
|
79
|
+
|
|
80
|
+
# Using encodings, too hard. See Mail::Message::Field::Full.
|
|
81
|
+
return '' if name.match(/\=\?.*?\?\=/)
|
|
82
|
+
|
|
83
|
+
# trim whitespace
|
|
84
|
+
name.sub!(/^\s+/, '')
|
|
85
|
+
name.sub!(/\s+$/, '')
|
|
86
|
+
name.sub!(/\s+/, ' ')
|
|
87
|
+
|
|
88
|
+
# Disregard numeric names (e.g. 123456.1234@compuserve.com)
|
|
89
|
+
return "" if name.match(/^[\d ]+$/)
|
|
90
|
+
|
|
91
|
+
name.sub!(/^\((.*)\)$/, '\1') # remove outermost parenthesis
|
|
92
|
+
name.sub!(/^"(.*)"$/, '\1') # remove outer quotation marks
|
|
93
|
+
name.gsub!(/\(.*?\)/, '') # remove minimal embedded comments
|
|
94
|
+
name.gsub!(/\\/, '') # remove all escapes
|
|
95
|
+
name.sub!(/^"(.*)"$/, '\1') # remove internal quotation marks
|
|
96
|
+
name.sub!(/^([^\s]+) ?, ?(.*)$/, '\2 \1') # reverse "Last, First M." if applicable
|
|
97
|
+
name.sub!(/,.*/, '')
|
|
98
|
+
|
|
99
|
+
# Change casing only when the name contains only upper or only
|
|
100
|
+
# lower cased characters.
|
|
101
|
+
unless ( name.match(/[A-Z]/) && name.match(/[a-z]/) ) then
|
|
102
|
+
# Set the case of the name to first char upper rest lower
|
|
103
|
+
name.gsub!(/\b(\w+)/io) {|w| $1.capitalize } # Upcase first letter on name
|
|
104
|
+
name.gsub!(/\bMc(\w)/io) { |w| "Mc#{$1.capitalize}" } # Scottish names such as 'McLeod'
|
|
105
|
+
name.gsub!(/\bo'(\w)/io) { |w| "O'#{$1.capitalize}" } # Irish names such as 'O'Malley, O'Reilly'
|
|
106
|
+
name.gsub!(/\b(x*(ix)?v*(iv)?i*)\b/io) { |w| $1.upcase } # Roman numerals, eg 'Level III Support'
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# some cleanup
|
|
110
|
+
name.gsub!(/\[[^\]]*\]/, '')
|
|
111
|
+
name.gsub!(/(^[\s'"]+|[\s'"]+$)/, '')
|
|
112
|
+
name.gsub!(/\s{2,}/, ' ')
|
|
113
|
+
name
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
|
|
2
|
+
module MailAddress
|
|
3
|
+
|
|
4
|
+
def self.parse(*addresses)
|
|
5
|
+
lines = addresses.grep(String)
|
|
6
|
+
line = lines.join('')
|
|
7
|
+
|
|
8
|
+
phrase, comment, address, objs = [], [], [], []
|
|
9
|
+
depth, idx = 0, 0
|
|
10
|
+
|
|
11
|
+
tokens = _tokenize lines
|
|
12
|
+
len = tokens.length
|
|
13
|
+
_next = _find_next idx, tokens, len
|
|
14
|
+
|
|
15
|
+
for idx in 0 ... len do
|
|
16
|
+
token = tokens[idx]
|
|
17
|
+
substr = token[0, 1]
|
|
18
|
+
if (substr == '(') then
|
|
19
|
+
comment.push(token)
|
|
20
|
+
elsif (token == '<') then
|
|
21
|
+
depth += 1
|
|
22
|
+
elsif (token == '>') then
|
|
23
|
+
depth -= 1 if depth > 0
|
|
24
|
+
elsif (token == ',' || token == ';') then
|
|
25
|
+
raise "Unmatched '<>' in line" if depth > 0
|
|
26
|
+
o = _complete(phrase, address, comment)
|
|
27
|
+
|
|
28
|
+
objs.push(o) if o
|
|
29
|
+
depth = 0
|
|
30
|
+
_next = _find_next idx+1, tokens, len
|
|
31
|
+
elsif (depth > 0) then
|
|
32
|
+
address.push(token)
|
|
33
|
+
elsif (_next == '<') then
|
|
34
|
+
phrase.push(token)
|
|
35
|
+
elsif ( token.match(/^[.\@:;]/) || address.empty? || address[-1].match(/^[.\@:;]/) ) then
|
|
36
|
+
address.push(token)
|
|
37
|
+
else
|
|
38
|
+
raise "Unmatched '<>' in line" if depth > 0
|
|
39
|
+
o = _complete(phrase, address, comment)
|
|
40
|
+
objs.push(o) if o
|
|
41
|
+
depth = 0
|
|
42
|
+
address.push(token)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
objs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def self._tokenize(addresses)
|
|
51
|
+
line = addresses.join(',') # $_
|
|
52
|
+
words, snippet, field = [], [], []
|
|
53
|
+
|
|
54
|
+
line.sub!(/\A\s+/, '')
|
|
55
|
+
line.gsub!(/[\r\n]+/,' ')
|
|
56
|
+
|
|
57
|
+
while (line != '')
|
|
58
|
+
field = ''
|
|
59
|
+
if ( line.sub!(/^\s*\(/, '(') ) # (...)
|
|
60
|
+
depth = 0
|
|
61
|
+
|
|
62
|
+
catch :PAREN do
|
|
63
|
+
while line.sub!(/\A(\(([^\(\)\\]|\\.)*)/, '') do
|
|
64
|
+
field << $1
|
|
65
|
+
depth += 1
|
|
66
|
+
while line.sub!(/\A(([^\(\)\\]|\\.)*\)\s*)/, '') do
|
|
67
|
+
field << $1
|
|
68
|
+
depth -= 1
|
|
69
|
+
throw :PAREN if depth == 0
|
|
70
|
+
field << $1 if line.sub!(/\A(([^\(\)\\]|\\.)+)/, '')
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
raise "Unmatched () '#{field}' '#{line}'" if depth > 0
|
|
75
|
+
|
|
76
|
+
field.sub!(/\s+\Z/, '')
|
|
77
|
+
words.push(field)
|
|
78
|
+
|
|
79
|
+
next
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
tmp = nil
|
|
83
|
+
if (
|
|
84
|
+
line.sub!(/\A("(?:[^"\\]+|\\.)*")\s*/, '') || # "..."
|
|
85
|
+
line.sub!(/\A(\[(?:[^\]\\]+|\\.)*\])\s*/, '') || # [...]
|
|
86
|
+
line.sub!(/\A([^\s()<>\@,;:\\".\[\]]+)\s*/, '') ||
|
|
87
|
+
line.sub!(/\A([()<>\@,;:\\".\[\]])\s*/, '')
|
|
88
|
+
)
|
|
89
|
+
words.push($1)
|
|
90
|
+
next
|
|
91
|
+
end
|
|
92
|
+
raise "Unrecognized line: #{line}"
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
words.push(',')
|
|
96
|
+
words
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self._find_next(idx, tokens, len)
|
|
100
|
+
while (idx < len)
|
|
101
|
+
c = tokens[idx]
|
|
102
|
+
return c if c == ',' || c == ';' || c == '<'
|
|
103
|
+
idx += 1
|
|
104
|
+
end
|
|
105
|
+
""
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self._complete (phrase, address, comment)
|
|
109
|
+
phrase.length > 0 || comment.length > 0 || address.length > 0 or return nil
|
|
110
|
+
new_address = MailAddress::Address.new(phrase.join(' '), address.join(''), comment.join(' '))
|
|
111
|
+
phrase.clear; address.clear; comment.clear
|
|
112
|
+
new_address
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
end
|
data/lib/mail_address.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require 'mail_address/version'
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "mail_address"
|
|
8
|
+
spec.version = MailAddress::VERSION
|
|
9
|
+
spec.authors = ["Kizashi Nagata"]
|
|
10
|
+
spec.email = ["kizashi1122@gmail.com"]
|
|
11
|
+
spec.summary = %q{Simple Mail Address Parser}
|
|
12
|
+
spec.description = %q{This library is implemented based on Perl Module Mail::Address.}
|
|
13
|
+
spec.homepage = "https://github.com/kizashi1122/mail_address"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
|
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
|
+
spec.require_paths = ["lib"]
|
|
20
|
+
|
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
|
22
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
|
23
|
+
spec.add_development_dependency 'rspec', '~> 3.1', '>= 3.1.0'
|
|
24
|
+
end
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'pp'
|
|
4
|
+
|
|
5
|
+
describe MailAddress do
|
|
6
|
+
|
|
7
|
+
it "normal case" do
|
|
8
|
+
line = "John 'M' Doe <john@example.com> (this is a comment), 大阪 太郎 <osaka@example.jp>"
|
|
9
|
+
results = MailAddress.parse(line)
|
|
10
|
+
|
|
11
|
+
expect(results[0].format).to eq("John 'M' Doe <john@example.com> (this is a comment)")
|
|
12
|
+
expect(results[0].address).to eq("john@example.com")
|
|
13
|
+
expect(results[0].name).to eq("John 'M' Doe")
|
|
14
|
+
expect(results[0].comment).to eq("(this is a comment)")
|
|
15
|
+
expect(results[0].phrase).to eq("John 'M' Doe")
|
|
16
|
+
expect(results[0].host).to eq("example.com")
|
|
17
|
+
expect(results[0].user).to eq("john")
|
|
18
|
+
|
|
19
|
+
# Perl module Mail::Address returns '大阪 太郎 <osaka@example.jp>' (no double quote)
|
|
20
|
+
# because regular expression \w matches even multibyte characters.
|
|
21
|
+
expect(results[1].format).to eq("\"大阪 太郎\" <osaka@example.jp>")
|
|
22
|
+
|
|
23
|
+
expect(results[1].address).to eq("osaka@example.jp")
|
|
24
|
+
expect(results[1].name).to eq("大阪 太郎")
|
|
25
|
+
expect(results[1].comment).to eq("")
|
|
26
|
+
expect(results[1].phrase).to eq("大阪 太郎")
|
|
27
|
+
expect(results[1].host).to eq("example.jp")
|
|
28
|
+
expect(results[1].user).to eq("osaka")
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'Perl Module Pod test data' do
|
|
32
|
+
|
|
33
|
+
data = [
|
|
34
|
+
[ '"Joe & J. Harvey" <ddd @Org>, JJV @ BBN',
|
|
35
|
+
'"Joe & J. Harvey" <ddd@Org>',
|
|
36
|
+
'Joe & J. Harvey'],
|
|
37
|
+
[ '"Joe & J. Harvey" <ddd @Org>',
|
|
38
|
+
'"Joe & J. Harvey" <ddd@Org>',
|
|
39
|
+
'Joe & J. Harvey'],
|
|
40
|
+
[ 'JJV @ BBN',
|
|
41
|
+
'JJV@BBN',
|
|
42
|
+
''],
|
|
43
|
+
[ '"spickett@tiac.net" <Sean.Pickett@zork.tiac.net>',
|
|
44
|
+
'"spickett@tiac.net" <Sean.Pickett@zork.tiac.net>',
|
|
45
|
+
'Spickett@Tiac.Net'],
|
|
46
|
+
[ 'rls@intgp8.ih.att.com (-Schieve,R.L.)',
|
|
47
|
+
'rls@intgp8.ih.att.com (-Schieve,R.L.)',
|
|
48
|
+
'R.L. -Schieve'],
|
|
49
|
+
[ 'bodg fred@tiuk.ti.com',
|
|
50
|
+
'bodg',
|
|
51
|
+
''],
|
|
52
|
+
[ 'm-sterni@mars.dsv.su.se',
|
|
53
|
+
'm-sterni@mars.dsv.su.se',
|
|
54
|
+
''],
|
|
55
|
+
[ 'jrh%cup.portal.com@portal.unix.portal.com',
|
|
56
|
+
'jrh%cup.portal.com@portal.unix.portal.com',
|
|
57
|
+
'Cup Portal Com'],
|
|
58
|
+
[ "astrachan@austlcm.sps.mot.com ('paul astrachan/xvt3')",
|
|
59
|
+
"astrachan@austlcm.sps.mot.com ('paul astrachan/xvt3')",
|
|
60
|
+
'Paul Astrachan/Xvt3'],
|
|
61
|
+
[ 'TWINE57%SDELVB.decnet@SNYBUFVA.CS.SNYBUF.EDU (JAMES R. TWINE - THE NERD)',
|
|
62
|
+
'TWINE57%SDELVB.decnet@SNYBUFVA.CS.SNYBUF.EDU (JAMES R. TWINE - THE NERD)',
|
|
63
|
+
'James R. Twine - The Nerd'],
|
|
64
|
+
[ 'David Apfelbaum <da0g+@andrew.cmu.edu>',
|
|
65
|
+
'David Apfelbaum <da0g+@andrew.cmu.edu>',
|
|
66
|
+
'David Apfelbaum'],
|
|
67
|
+
[ '"JAMES R. TWINE - THE NERD" <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>',
|
|
68
|
+
'"JAMES R. TWINE - THE NERD" <TWINE57%SDELVB%SNYDELVA.bitnet@CUNYVM.CUNY.EDU>',
|
|
69
|
+
'James R. Twine - The Nerd'],
|
|
70
|
+
[ 'bilsby@signal.dra (Fred C. M. Bilsby)',
|
|
71
|
+
'bilsby@signal.dra (Fred C. M. Bilsby)',
|
|
72
|
+
'Fred C. M. Bilsby'],
|
|
73
|
+
[ '/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk',
|
|
74
|
+
'/G=Owen/S=Smith/O=SJ-Research/ADMD=INTERSPAN/C=GB/@mhs-relay.ac.uk',
|
|
75
|
+
'Owen Smith'],
|
|
76
|
+
[ 'apardon@rc1.vub.ac.be (Antoon Pardon)',
|
|
77
|
+
'apardon@rc1.vub.ac.be (Antoon Pardon)',
|
|
78
|
+
'Antoon Pardon'],
|
|
79
|
+
['"Stephen Burke, Liverpool" <BURKE@vxdsya.desy.de>',
|
|
80
|
+
'"Stephen Burke, Liverpool" <BURKE@vxdsya.desy.de>',
|
|
81
|
+
'Stephen Burke'],
|
|
82
|
+
['Andy Duplain <duplain@btcs.bt.co.uk>',
|
|
83
|
+
'Andy Duplain <duplain@btcs.bt.co.uk>',
|
|
84
|
+
'Andy Duplain'],
|
|
85
|
+
['Gunnar Zoetl <zoetl@isa.informatik.th-darmstadt.de>',
|
|
86
|
+
'Gunnar Zoetl <zoetl@isa.informatik.th-darmstadt.de>',
|
|
87
|
+
'Gunnar Zoetl'],
|
|
88
|
+
['The Newcastle Info-Server <info-admin@newcastle.ac.uk>',
|
|
89
|
+
'The Newcastle Info-Server <info-admin@newcastle.ac.uk>',
|
|
90
|
+
'The Newcastle Info-Server'],
|
|
91
|
+
['wsinda@nl.tue.win.info (Dick Alstein)',
|
|
92
|
+
'wsinda@nl.tue.win.info (Dick Alstein)',
|
|
93
|
+
'Dick Alstein'],
|
|
94
|
+
['mserv@rusmv1.rus.uni-stuttgart.de (RUS Mail Server)',
|
|
95
|
+
'mserv@rusmv1.rus.uni-stuttgart.de (RUS Mail Server)',
|
|
96
|
+
'RUS Mail Server'],
|
|
97
|
+
['Suba.Peddada@eng.sun.com (Suba Peddada [CONTRACTOR])',
|
|
98
|
+
'Suba.Peddada@eng.sun.com (Suba Peddada [CONTRACTOR])',
|
|
99
|
+
'Suba Peddada'],
|
|
100
|
+
['ftpmail-adm@info2.rus.uni-stuttgart.de',
|
|
101
|
+
'ftpmail-adm@info2.rus.uni-stuttgart.de',
|
|
102
|
+
''],
|
|
103
|
+
['Paul Manser (0032 memo) <a906187@tiuk.ti.com>',
|
|
104
|
+
'Paul Manser <a906187@tiuk.ti.com> (0032 memo)',
|
|
105
|
+
'Paul Manser'],
|
|
106
|
+
['"gregg (g.) woodcock" <woodcock@bnr.ca>',
|
|
107
|
+
'"gregg (g.) woodcock" <woodcock@bnr.ca>',
|
|
108
|
+
'Gregg Woodcock'],
|
|
109
|
+
['Clive Bittlestone <clyvb@asic.sc.ti.com>',
|
|
110
|
+
'Clive Bittlestone <clyvb@asic.sc.ti.com>',
|
|
111
|
+
'Clive Bittlestone'],
|
|
112
|
+
['Graham.Barr@tiuk.ti.com',
|
|
113
|
+
'Graham.Barr@tiuk.ti.com',
|
|
114
|
+
'Graham Barr'],
|
|
115
|
+
['"Graham Bisset, UK Net Support, +44 224 728109" <GRAHAM@dyce.wireline.slb.com.ti.com.>',
|
|
116
|
+
'"Graham Bisset, UK Net Support, +44 224 728109" <GRAHAM@dyce.wireline.slb.com.ti.com.>',
|
|
117
|
+
'Graham Bisset'],
|
|
118
|
+
['a909937 (Graham Barr (0004 bodg))',
|
|
119
|
+
'a909937 (Graham Barr (0004 bodg))',
|
|
120
|
+
'Graham Barr'],
|
|
121
|
+
['a909062@node_cb83.node_cb83 (Colin x Maytum (0013 bro5))',
|
|
122
|
+
'a909062@node_cb83.node_cb83 (Colin x Maytum (0013 bro5))',
|
|
123
|
+
'Colin x Maytum'],
|
|
124
|
+
['a909062@node_cb83.node_cb83 (Colin Maytum (0013 bro5))',
|
|
125
|
+
'a909062@node_cb83.node_cb83 (Colin Maytum (0013 bro5))',
|
|
126
|
+
'Colin Maytum'],
|
|
127
|
+
['Derek.Roskell%dero@msg.ti.com',
|
|
128
|
+
'Derek.Roskell%dero@msg.ti.com',
|
|
129
|
+
'Derek Roskell'],
|
|
130
|
+
['":sysmail"@ Some-Group. Some-Org, Muhammed.(I am the greatest) Ali @(the)Vegas.WBA',
|
|
131
|
+
'":sysmail"@Some-Group.Some-Org',
|
|
132
|
+
''],
|
|
133
|
+
["david d `zoo' zuhn <zoo@aggregate.com>",
|
|
134
|
+
"david d `zoo' zuhn <zoo@aggregate.com>",
|
|
135
|
+
"David D `Zoo' Zuhn"],
|
|
136
|
+
['"Christopher S. Arthur" <csa@halcyon.com>',
|
|
137
|
+
'"Christopher S. Arthur" <csa@halcyon.com>',
|
|
138
|
+
'Christopher S. Arthur'],
|
|
139
|
+
['Jeffrey A Law <law@snake.cs.utah.edu>',
|
|
140
|
+
'Jeffrey A Law <law@snake.cs.utah.edu>',
|
|
141
|
+
'Jeffrey A Law'],
|
|
142
|
+
['lidl@uunet.uu.net (Kurt J. Lidl)',
|
|
143
|
+
'lidl@uunet.uu.net (Kurt J. Lidl)',
|
|
144
|
+
'Kurt J. Lidl'],
|
|
145
|
+
['Kresten_Thorup@NeXT.COM (Kresten Krab Thorup)',
|
|
146
|
+
'Kresten_Thorup@NeXT.COM (Kresten Krab Thorup)',
|
|
147
|
+
'Kresten Krab Thorup'],
|
|
148
|
+
['hjl@nynexst.com (H.J. Lu)',
|
|
149
|
+
'hjl@nynexst.com (H.J. Lu)',
|
|
150
|
+
'H.J. Lu'],
|
|
151
|
+
['@oleane.net:hugues@afp.com a!b@c.d foo!bar!foobar!root',
|
|
152
|
+
'@oleane.net:hugues@afp.com',
|
|
153
|
+
'Oleane Net:Hugues'],
|
|
154
|
+
# ['(foo@bar.com (foobar), ned@foo.com (nedfoo) ) <kevin@goess.org>',
|
|
155
|
+
# 'kevin@goess.org (foo@bar.com (foobar), ned@foo.com (nedfoo) )',
|
|
156
|
+
# ''],
|
|
157
|
+
["eBay's Half <half@ebay.com>",
|
|
158
|
+
"eBay's Half <half@ebay.com>",
|
|
159
|
+
"eBay's Half"],
|
|
160
|
+
['outlook@example.com; semicolons@example.com',
|
|
161
|
+
'outlook@example.com',
|
|
162
|
+
''],
|
|
163
|
+
['"Foo; Bar" <both@example.com>, Baz <baz@example.com>',
|
|
164
|
+
'"Foo; Bar" <both@example.com>',
|
|
165
|
+
'Foo; Bar']
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
data.each do |d|
|
|
169
|
+
test_src = d[0]
|
|
170
|
+
exp_format = d[1]
|
|
171
|
+
exp_name = d[2]
|
|
172
|
+
p test_src
|
|
173
|
+
result = MailAddress.parse(test_src)[0]
|
|
174
|
+
|
|
175
|
+
result_format = result.format || ""
|
|
176
|
+
result_name = result.name || ""
|
|
177
|
+
|
|
178
|
+
expect(result_name).to eq(exp_name)
|
|
179
|
+
expect(result_format).to eq(exp_format)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: mail_address
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.1
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Kizashi Nagata
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2015-01-06 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '1.7'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.7'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '10.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '10.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.1'
|
|
48
|
+
- - ">="
|
|
49
|
+
- !ruby/object:Gem::Version
|
|
50
|
+
version: 3.1.0
|
|
51
|
+
type: :development
|
|
52
|
+
prerelease: false
|
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
54
|
+
requirements:
|
|
55
|
+
- - "~>"
|
|
56
|
+
- !ruby/object:Gem::Version
|
|
57
|
+
version: '3.1'
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: 3.1.0
|
|
61
|
+
description: This library is implemented based on Perl Module Mail::Address.
|
|
62
|
+
email:
|
|
63
|
+
- kizashi1122@gmail.com
|
|
64
|
+
executables: []
|
|
65
|
+
extensions: []
|
|
66
|
+
extra_rdoc_files: []
|
|
67
|
+
files:
|
|
68
|
+
- ".gitignore"
|
|
69
|
+
- ".rspec"
|
|
70
|
+
- ".travis.yml"
|
|
71
|
+
- Gemfile
|
|
72
|
+
- LICENSE.txt
|
|
73
|
+
- README.md
|
|
74
|
+
- Rakefile
|
|
75
|
+
- lib/mail_address.rb
|
|
76
|
+
- lib/mail_address/address.rb
|
|
77
|
+
- lib/mail_address/mail_address.rb
|
|
78
|
+
- lib/mail_address/version.rb
|
|
79
|
+
- mail_address.gemspec
|
|
80
|
+
- spec/mail_address_spec.rb
|
|
81
|
+
- spec/spec_helper.rb
|
|
82
|
+
homepage: https://github.com/kizashi1122/mail_address
|
|
83
|
+
licenses:
|
|
84
|
+
- MIT
|
|
85
|
+
metadata: {}
|
|
86
|
+
post_install_message:
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '0'
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubyforge_project:
|
|
102
|
+
rubygems_version: 2.4.1
|
|
103
|
+
signing_key:
|
|
104
|
+
specification_version: 4
|
|
105
|
+
summary: Simple Mail Address Parser
|
|
106
|
+
test_files:
|
|
107
|
+
- spec/mail_address_spec.rb
|
|
108
|
+
- spec/spec_helper.rb
|