full-name-splitter 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.
@@ -0,0 +1,58 @@
1
+ *FullNameSplitter* splits full name into first and last name considering name prefixes and initials
2
+
3
+ If you include the module it requires attribute accessors first\_name and last\_name and adds #full\_name, #full\_name= to the class
4
+
5
+ For example
6
+
7
+ require 'full_name_splitter'
8
+
9
+ class Incognito
10
+ include FullNameSplitter
11
+ attr_accessor :first_name, :last_name
12
+ end
13
+
14
+ incognito = Incognito.new :full_name => "George H. W. Bush"
15
+ incognito.first_name # => "George H. W."
16
+ incognito.last_name # => "Bush"
17
+
18
+ incognito = Incognito.new :full_name => "Kevin J. O'Connor"
19
+ incognito.first_name # => "Kevin J."
20
+ incognito.last_name # => "O'Connor"
21
+
22
+ incognito = Incognito.new :full_name => "Thomas G. Della Fave"
23
+ incognito.first_name # => "Thomas G."
24
+ incognito.last_name # => "Della Fave"
25
+
26
+ incognito = Incognito.new :full_name => "Gabriel Van Helsing"
27
+ incognito.first_name # => "Gabriel"
28
+ incognito.last_name # => "Van Helsing"
29
+
30
+ If full name isn't complete *FullNameSplitter* tries to split partially
31
+
32
+ incognito = Incognito.new :full_name => "George W."
33
+ incognito.first_name # => "George W."
34
+ incognito.last_name # => nil
35
+
36
+ incognito = Incognito.new :full_name => "George"
37
+ incognito.first_name # => "George"
38
+ incognito.last_name # => nil
39
+
40
+ incognito = Incognito.new :full_name => "Van Helsing"
41
+ incognito.first_name # => nil
42
+ incognito.last_name # => "Van Helsing"
43
+
44
+ incognito = Incognito.new :full_name => "d'Artagnan"
45
+ incognito.first_name # => nil
46
+ incognito.last_name # => "d'Artagnan"
47
+
48
+ For other examples see _spec/lib/full\_name\_splitter\_spec.rb_
49
+
50
+ Also you can use splitter directly by calling module function FullNameSplitter::split
51
+
52
+ FullNameSplitter.split("Juan Martín de la Cruz Gómez") # => ["Juan Martín", "de la Cruz Gómez"]
53
+ FullNameSplitter.split("Ludwig Mies van der Rohe") # => ["Ludwig", "Mies van der Rohe"]
54
+
55
+ If the lib can't split a name correctly, it is possible to split by comma
56
+
57
+ FullNameSplitter.split("John Quincy Adams") # => ["John Quincy", "Adams"]
58
+ FullNameSplitter.split("John, Quincy Adams") # => ["John", "Quincy Adams"]
@@ -0,0 +1,26 @@
1
+ require "rubygems"
2
+ require "spec/rake/spectask"
3
+
4
+ task :default => :spec
5
+
6
+ desc "Run all specification examples"
7
+ Spec::Rake::SpecTask.new do |t|
8
+ t.spec_opts = ['--options', "spec/spec.opts"]
9
+ t.spec_files = FileList['spec/**/*_spec.rb']
10
+ end
11
+
12
+
13
+ begin
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gemspec|
16
+ gemspec.name = "full-name-splitter"
17
+ gemspec.summary = "*FullNameSplitter* splits full name into first and last name considering name prefixes and initials"
18
+ gemspec.description = ""
19
+ gemspec.email = "trevor@trevorcreech.com"
20
+ gemspec.homepage = "http://github.com/zedlander/full-name-splitter"
21
+ gemspec.authors = ["Pavel Gorbokon", "Trevor Creech"]
22
+ end
23
+ Jeweler::GemcutterTasks.new
24
+ rescue LoadError
25
+ puts "Jeweler not available. Install it with: gem install jeweler"
26
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,18 @@
1
+ Feature: Split partial name
2
+ In order to split full name into first name and last name
3
+ As a full name holder
4
+ I want to get first name and last name
5
+
6
+ Scenario Outline: Partial Names
7
+ Given Incognito instance object
8
+ When I assign <full_name> to incognito
9
+ Then he should have partial <first_name> or partial <last_name>
10
+
11
+ Examples:
12
+ | full_name | first_name | last_name |
13
+ | Van Helsing | nil | "Van Helsing" |
14
+ | d'Artagnan | nil | "d'Artagnan" |
15
+ | O'Connor | nil | "O'Connor" |
16
+ | George | "George" | nil |
17
+ | Kevin J. | "Kevin J." | nil |
18
+ | George H. W. | "George H. W." | nil |
@@ -0,0 +1,93 @@
1
+ Feature: Split given full name
2
+ In order to split full name into first name and last name
3
+ As a full name holder
4
+ I want to get first name and last name
5
+
6
+ Scenario Outline: American/European
7
+ Given Incognito instance object
8
+ When I assign <full_name> to incognito
9
+ Then he should have a <first_name> and a <last_name>
10
+
11
+ Examples:
12
+ | full_name | first_name |last_name |
13
+ | John Smith | John | Smith |
14
+ | Kevin J. O'Connor | Kevin J. | O'Connor |
15
+ | George W Bush | George W | Bush |
16
+ | George H. W. Bush | George H. W. | Bush |
17
+ | James K. Polk | James K. | Polk |
18
+ | William Henry Harrison | William Henry | Harrison |
19
+ | John Quincy Adams | John Quincy | Adams |
20
+ | John Quincy | John | Quincy |
21
+
22
+ Scenario Outline: French
23
+ Given Incognito instance object
24
+ When I assign <full_name> to incognito
25
+ Then he should have a <first_name> and a <last_name>
26
+
27
+ Examples:
28
+ | full_name | first_name | last_name |
29
+ | Pierre de Montesquiou | Pierre | de Montesquiou |
30
+ | Charles d'Artagnan | Charles | d'Artagnan |
31
+ | Anne du Bourg | Anne | du Bourg |
32
+
33
+ Scenario Outline: Italian
34
+ Given Incognito instance object
35
+ When I assign <full_name> to incognito
36
+ Then he should have a <first_name> and a <last_name>
37
+
38
+ Examples:
39
+ | full_name | first_name | last_name |
40
+ | Maria del Carmen Menendez | Maria | del Carmen Menendez |
41
+ | Alessandro Del Piero | Alessandro | Del Piero |
42
+ | Thomas G. Della Fave | Thomas G. | Della Fave |
43
+ | Federica Pellegrini | Federica | Pellegrini |
44
+ | Leonardo da Vinci | Leonardo | da Vinci |
45
+ | Alberto Del Sole | Alberto | Del Sole |
46
+ | Adriano Dello Spavento | Adriano | Dello Spavento |
47
+ | Luca Delle Fave | Luca | Delle Fave |
48
+ | Francesca Della Valle | Francesca | Della Valle |
49
+ | Guido Delle Colonne | Guido | Delle Colonne |
50
+ | Tomasso D'Arco | Tomasso | D'Arco |
51
+
52
+ Scenario Outline: German
53
+ Given Incognito instance object
54
+ When I assign <full_name> to incognito
55
+ Then he should have a <first_name> and a <last_name>
56
+
57
+ Examples:
58
+ | full_name | first_name | last_name |
59
+ | Ludwig Mies van der Rohe | Ludwig | Mies van der Rohe |
60
+ | Johann Wolfgang von Goethe | Johann Wolfgang | von Goethe |
61
+
62
+ Scenario Outline: Dutch
63
+ Given Incognito instance object
64
+ When I assign <full_name> to incognito
65
+ Then he should have a <first_name> and a <last_name>
66
+
67
+ Examples:
68
+ | full_name | first_name | last_name |
69
+ | Gabriel Van Helsing | Gabriel | Van Helsing |
70
+ | Johan de heer Van Kampen | Johan | de heer Van Kampen |
71
+ | Han Van De Casteele | Han | Van De Casteele |
72
+ | Han Vande Casteele | Han | Vande Casteele |
73
+
74
+ Scenario Outline: Spanish
75
+ Given Incognito instance object
76
+ When I assign <full_name> to incognito
77
+ Then he should have a <first_name> and a <last_name>
78
+
79
+ Examples:
80
+ | full_name | first_name | last_name |
81
+ | Juan Martín de la Cruz Gómez | Juan Martín | de la Cruz Gómez |
82
+ | Javier Reyes de la Barrera | Javier | Reyes de la Barrera |
83
+ | Rosa María Pérez Martínez Vda. de la Cruz | Rosa María | Pérez Martínez Vda. de la Cruz |
84
+
85
+ Scenario Outline: Asian
86
+ Given Incognito instance object
87
+ When I assign <full_name> to incognito
88
+ Then he should have a <first_name> and a <last_name>
89
+
90
+ Examples:
91
+ | full_name | first_name | last_name |
92
+ | Jaazaniah ben Shaphan | Jaazaniah | ben Shaphan |
93
+ | Noda' bi-Yehudah | Noda' | bi-Yehudah |
@@ -0,0 +1,17 @@
1
+ Given /^Incognito instance object$/ do
2
+ @incognito = Incognito.new
3
+ end
4
+
5
+ When /^I assign (.+) to incognito$/ do |full_name|
6
+ @incognito.full_name = full_name
7
+ end
8
+
9
+ Then /^he should have a (.+) and a (.+)$/ do |first_name, last_name|
10
+ @incognito.first_name.should == first_name
11
+ @incognito.last_name.should == last_name
12
+ end
13
+
14
+ Then /^he should have partial (.+) or partial (.+)$/ do |first_name, last_name|
15
+ @incognito.first_name.inspect.should == first_name
16
+ @incognito.last_name.inspect.should == last_name
17
+ end
@@ -0,0 +1,6 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../../spec/spec_helper.rb')
2
+
3
+ class Incognito
4
+ include FullNameSplitter
5
+ attr_accessor :first_name, :last_name
6
+ end
@@ -0,0 +1,52 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{full-name-splitter}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Pavel Gorbokon", "Trevor Creech"]
12
+ s.date = %q{2010-09-10}
13
+ s.description = %q{}
14
+ s.email = %q{trevor@trevorcreech.com}
15
+ s.extra_rdoc_files = [
16
+ "README.mdown"
17
+ ]
18
+ s.files = [
19
+ "README.mdown",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "features/partial_split.feature",
23
+ "features/split.feature",
24
+ "features/step_definitions/split_steps.rb",
25
+ "features/support/env.rb",
26
+ "full-name-splitter.gemspec",
27
+ "lib/full-name-splitter.rb",
28
+ "spec/lib/full_name_splitter_spec.rb",
29
+ "spec/spec.opts",
30
+ "spec/spec_helper.rb"
31
+ ]
32
+ s.homepage = %q{http://github.com/zedlander/full-name-splitter}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.7}
36
+ s.summary = %q{*FullNameSplitter* splits full name into first and last name considering name prefixes and initials}
37
+ s.test_files = [
38
+ "spec/lib/full_name_splitter_spec.rb",
39
+ "spec/spec_helper.rb"
40
+ ]
41
+
42
+ if s.respond_to? :specification_version then
43
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
44
+ s.specification_version = 3
45
+
46
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
47
+ else
48
+ end
49
+ else
50
+ end
51
+ end
52
+
@@ -0,0 +1,105 @@
1
+ # -*- coding: utf-8 -*-
2
+ # requires full accessable first_name and last_name attributes
3
+ module FullNameSplitter
4
+
5
+ PREFIXES = %w(de da la du del dei vda. dello della degli delle van von der den heer ten ter vande vanden vander voor ver aan mc ben).freeze
6
+
7
+ class Splitter
8
+
9
+ def initialize(full_name)
10
+ @full_name = full_name
11
+ @first_name = []
12
+ @last_name = []
13
+ split!
14
+ end
15
+
16
+ def split!
17
+ @units = @full_name.split(/\s+/)
18
+ while @unit = @units.shift do
19
+ if prefix? or with_apostrophe? or (first_name? and last_unit? and not initial?)
20
+ @last_name << @unit and break
21
+ else
22
+ @first_name << @unit
23
+ end
24
+ end
25
+ @last_name += @units
26
+
27
+ adjust_exceptions!
28
+ end
29
+
30
+ def first_name
31
+ @first_name.empty? ? nil : @first_name.join(' ')
32
+ end
33
+
34
+ def last_name
35
+ @last_name.empty? ? nil : @last_name.join(' ')
36
+ end
37
+
38
+ private
39
+
40
+ def prefix?
41
+ PREFIXES.include?(@unit.downcase)
42
+ end
43
+
44
+ # M or W.
45
+ def initial?
46
+ @unit =~ /^\w\.?$/
47
+ end
48
+
49
+ # O'Connor, d'Artagnan match
50
+ # Noda' doesn't match
51
+ def with_apostrophe?
52
+ @unit =~ /\w{1}'\w+/
53
+ end
54
+
55
+ def last_unit?
56
+ @units.empty?
57
+ end
58
+
59
+ def first_name?
60
+ not @first_name.empty?
61
+ end
62
+
63
+ def adjust_exceptions!
64
+ return if @first_name.size <= 1
65
+
66
+ # Adjusting exceptions like
67
+ # "Ludwig Mies van der Rohe" => ["Ludwig", "Mies van der Rohe" ]
68
+ # "Juan Martín de la Cruz Gómez" => ["Juan Martín", "de la Cruz Gómez" ]
69
+ # "Javier Reyes de la Barrera" => ["Javier", "Reyes de la Barrera" ]
70
+ # Rosa María Pérez Martínez Vda. de la Cruz
71
+ # => ["Rosa María", "Pérez Martínez Vda. de la Cruz"]
72
+ if last_name =~ /^(van der|(vda\. )?de la \w+$)/i
73
+ loop do
74
+ @last_name.unshift @first_name.pop
75
+ break if @first_name.size <= 2
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ def full_name
82
+ [first_name, last_name].compact.join(' ')
83
+ end
84
+
85
+ def full_name=(name)
86
+ self.first_name, self.last_name = split(name)
87
+ end
88
+
89
+ private
90
+
91
+ def split(name)
92
+ name = name.to_s.strip.gsub(/\s+/, ' ')
93
+
94
+ if name.include?(',')
95
+ name.
96
+ split(/\s*,\s*/, 2). # ",van helsing" produces ["", "van helsing"]
97
+ map{ |u| u.empty? ? nil : u } # but it should be [nil, "van helsing"] by lib convection
98
+ else
99
+ splitter = Splitter.new(name)
100
+ [splitter.first_name, splitter.last_name]
101
+ end
102
+ end
103
+
104
+ module_function :split
105
+ end
@@ -0,0 +1,114 @@
1
+ # -*- coding: utf-8 -*-
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ class Incognito
5
+ include FullNameSplitter
6
+ attr_accessor :first_name, :last_name
7
+ end
8
+
9
+ describe Incognito do
10
+ describe "#full_name=" do
11
+
12
+ #
13
+ # Environment
14
+ #
15
+
16
+ subject { Incognito.new }
17
+
18
+ def gum(first, last)
19
+ "[#{first}] + [#{last}]"
20
+ end
21
+
22
+
23
+ #
24
+ # Examples
25
+ #
26
+
27
+ {
28
+ "John Smith" => ["John", "Smith" ],
29
+
30
+ "Kevin J. O'Connor" => ["Kevin J.", "O'Connor" ],
31
+ "Gabriel Van Helsing" => ["Gabriel", "Van Helsing" ],
32
+ "Pierre de Montesquiou" => ["Pierre", "de Montesquiou" ],
33
+ "Charles d'Artagnan" => ["Charles", "d'Artagnan" ],
34
+ "Jaazaniah ben Shaphan" => ["Jaazaniah", "ben Shaphan" ],
35
+ "Noda' bi-Yehudah" => ["Noda'", "bi-Yehudah" ],
36
+ "Maria del Carmen Menendez" => ["Maria", "del Carmen Menendez" ],
37
+ "Alessandro Del Piero" => ["Alessandro", "Del Piero" ],
38
+
39
+ "George W Bush" => ["George W", "Bush" ],
40
+ "George H. W. Bush" => ["George H. W.", "Bush" ],
41
+ "James K. Polk" => ["James K.", "Polk" ],
42
+ "William Henry Harrison" => ["William Henry", "Harrison" ],
43
+ "John Quincy Adams" => ["John Quincy", "Adams" ],
44
+
45
+ "John Quincy" => ["John", "Quincy" ],
46
+ "George H. W." => ["George H. W.", nil ],
47
+ "Van Helsing" => [nil, "Van Helsing" ],
48
+ "d'Artagnan" => [nil, "d'Artagnan" ],
49
+ "O'Connor" => [nil, "O'Connor" ],
50
+
51
+ "George" => ["George", nil ],
52
+ "Kevin J. " => ["Kevin J.", nil ],
53
+
54
+ "Thomas G. Della Fave" => ["Thomas G.", "Della Fave" ],
55
+ "Anne du Bourg" => ["Anne", "du Bourg" ],
56
+
57
+ # German
58
+ "Johann Wolfgang von Goethe" => ["Johann Wolfgang", "von Goethe" ],
59
+
60
+ # Spanish-speaking countries
61
+ "Juan Martín de la Cruz Gómez" => ["Juan Martín", "de la Cruz Gómez" ],
62
+ "Javier Reyes de la Barrera" => ["Javier", "Reyes de la Barrera" ],
63
+ "Rosa María Pérez Martínez Vda. de la Cruz" =>
64
+ ["Rosa María", "Pérez Martínez Vda. de la Cruz"],
65
+
66
+ # Italian
67
+ "Federica Pellegrini" => ["Federica", "Pellegrini" ],
68
+ "Leonardo da Vinci" => ["Leonardo", "da Vinci" ],
69
+ # sounds like a fancy medival action movie star pseudonim
70
+ "Alberto Del Sole" => ["Alberto", "Del Sole" ],
71
+ # horror movie star pseudonim?
72
+ "Adriano Dello Spavento" => ["Adriano", "Dello Spavento" ],
73
+ "Luca Delle Fave" => ["Luca", "Delle Fave" ],
74
+ "Francesca Della Valle" => ["Francesca", "Della Valle" ],
75
+ "Guido Delle Colonne" => ["Guido", "Delle Colonne" ],
76
+ "Tomasso D'Arco" => ["Tomasso", "D'Arco" ],
77
+
78
+ # Dutch
79
+ "Johan de heer Van Kampen" => ["Johan", "de heer Van Kampen" ],
80
+ "Han Van De Casteele" => ["Han", "Van De Casteele" ],
81
+ "Han Vande Casteele" => ["Han", "Vande Casteele" ],
82
+
83
+ # Exceptions?
84
+ # the architect Ludwig Mies van der Rohe, from the West German city of Aachen, was originally Ludwig Mies;
85
+ "Ludwig Mies van der Rohe" => ["Ludwig", "Mies van der Rohe" ],
86
+
87
+ # If comma is provided then split by comma
88
+
89
+ "John, Quincy Adams" => ["John", "Quincy Adams" ],
90
+ "Ludwig Mies, van der Rohe" => ["Ludwig Mies", "van der Rohe" ],
91
+
92
+ # Test ignoring unnecessary whitespaces
93
+ "\t Ludwig Mies\t van der Rohe " => ["Ludwig", "Mies van der Rohe" ],
94
+ "\t Ludwig Mies,\t van der Rohe " => ["Ludwig Mies", "van der Rohe" ],
95
+ "\t Ludwig " => ["Ludwig", nil ],
96
+ " van helsing " => [nil, "van helsing" ],
97
+ " , van helsing " => [nil, "van helsing" ],
98
+ "\t Ludwig Mies,\t van der Rohe " => ["Ludwig Mies", "van der Rohe" ],
99
+
100
+ }.
101
+
102
+ each do |full_name, split_name|
103
+ it "should split #{full_name} to '#{split_name.first}' and '#{split_name.last}'" do
104
+ subject.full_name = full_name
105
+ gum(subject.first_name, subject.last_name).should == gum(*split_name)
106
+ end
107
+
108
+ it "should split #{full_name} to '#{split_name.first}' and '#{split_name.last}' when called as module function" do
109
+ FullNameSplitter.split(full_name).should == split_name
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format specdoc
@@ -0,0 +1 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../lib/full_name_splitter.rb')
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: full-name-splitter
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Pavel Gorbokon
14
+ - Trevor Creech
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2010-09-10 00:00:00 -07:00
20
+ default_executable:
21
+ dependencies: []
22
+
23
+ description: ""
24
+ email: trevor@trevorcreech.com
25
+ executables: []
26
+
27
+ extensions: []
28
+
29
+ extra_rdoc_files:
30
+ - README.mdown
31
+ files:
32
+ - README.mdown
33
+ - Rakefile
34
+ - VERSION
35
+ - features/partial_split.feature
36
+ - features/split.feature
37
+ - features/step_definitions/split_steps.rb
38
+ - features/support/env.rb
39
+ - full-name-splitter.gemspec
40
+ - lib/full-name-splitter.rb
41
+ - spec/lib/full_name_splitter_spec.rb
42
+ - spec/spec.opts
43
+ - spec/spec_helper.rb
44
+ has_rdoc: true
45
+ homepage: http://github.com/zedlander/full-name-splitter
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options:
50
+ - --charset=UTF-8
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 3
59
+ segments:
60
+ - 0
61
+ version: "0"
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ hash: 3
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ requirements: []
72
+
73
+ rubyforge_project:
74
+ rubygems_version: 1.3.7
75
+ signing_key:
76
+ specification_version: 3
77
+ summary: "*FullNameSplitter* splits full name into first and last name considering name prefixes and initials"
78
+ test_files:
79
+ - spec/lib/full_name_splitter_spec.rb
80
+ - spec/spec_helper.rb