full-name-splitter 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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