japanese_names 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/README.md +22 -27
- data/lib/japanese_names/backend/memory/store.rb +33 -17
- data/lib/japanese_names/enamdict.rb +9 -8
- data/lib/japanese_names/finder.rb +5 -5
- data/lib/japanese_names/splitter.rb +49 -24
- data/lib/japanese_names/util/kernel.rb +24 -0
- data/lib/japanese_names/util/ngram.rb +40 -37
- data/lib/japanese_names/version.rb +3 -1
- data/lib/japanese_names.rb +5 -2
- data/spec/config.yml +422 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/unit/finder_spec.rb +5 -30
- data/spec/unit/ngram_spec.rb +21 -10
- data/spec/unit/splitter_spec.rb +21 -29
- metadata +6 -4
- data/lib/japanese_names/backend/memory/finder.rb +0 -55
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6da3f9dacc4174a93a90ea9bb7dd707d4a51346c
|
|
4
|
+
data.tar.gz: 164351ec8ed4957d82bef3001142b802562c10c0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30db2c3ae0959b4012e79ea257a2dcb87a6b86964fb1934540689e7b751c36a98f3749c6334a67044f3516258e67fb984ada3be8db13d1d59837072523fd76a6
|
|
7
|
+
data.tar.gz: 493dc8d0ed918f1e213cc7bf0526ac21298ea64d4915e4fdc4a592727dbd0c577d8ddda12ce432dba25746a9d28fddb960c29688c207cebb33b784b5f5efafa8
|
data/README.md
CHANGED
|
@@ -39,7 +39,7 @@ Note that romaji data has been removed from our `enamdict.min` file in the compr
|
|
|
39
39
|
|
|
40
40
|
### Splitter#split
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
The main method is `split` which, given a kanji and kana representation of a name splits
|
|
43
43
|
into to family/given names.
|
|
44
44
|
|
|
45
45
|
```ruby
|
|
@@ -47,36 +47,46 @@ into to family/given names.
|
|
|
47
47
|
splitter.split('堺雅美', 'さかいマサミ') #=> [['堺', '雅美'], ['さかい', 'マサミ']]
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
Over a test corpus of over 22,000 names it yields a failure rate of less than 0.5%.
|
|
51
|
+
|
|
50
52
|
The logic is as follows:
|
|
51
53
|
|
|
52
|
-
* Step 1: Split kanji name into possible
|
|
54
|
+
* Step 1: Split kanji name into possible sub-strings from the middle out-ward.
|
|
53
55
|
|
|
54
56
|
```
|
|
55
57
|
上原亜沙子 =>
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
上
|
|
59
|
+
上原 亜沙子
|
|
60
|
+
上原亜 沙子
|
|
61
|
+
上 原亜沙子
|
|
62
|
+
上原亜沙 子
|
|
62
63
|
```
|
|
63
64
|
|
|
64
65
|
* Step 2: Lookup possible kana matches in dictionary (done in a single pass)
|
|
65
66
|
|
|
66
67
|
```
|
|
67
|
-
上原亜沙子 => X
|
|
68
|
-
上原亜沙 => X
|
|
69
|
-
上原亜 => X
|
|
70
68
|
上原 => かみはら かみばら うえはら うえばら...
|
|
69
|
+
亜沙子 => あさこ
|
|
70
|
+
上原亜 => X
|
|
71
|
+
亜沙 => さこ
|
|
71
72
|
上 => かみ うえ ...
|
|
73
|
+
原亜沙子 => X
|
|
74
|
+
...
|
|
72
75
|
```
|
|
73
76
|
|
|
74
|
-
* Step 3: Compare kana lookups versus kana name and detect first match
|
|
77
|
+
* Step 3: Compare kana lookups versus kana name and detect first match.
|
|
78
|
+
If the kana string can be matched from both sides and yield the same result,
|
|
79
|
+
we will return that result immediately. Otherwise we return the first single sided match
|
|
80
|
+
found.
|
|
75
81
|
|
|
76
82
|
```
|
|
77
83
|
うえはらあさこ contains かみはら ? => X
|
|
78
84
|
うえはらあさこ contains かみばら ? => X
|
|
79
85
|
うえはらあさこ contains うえはら ? => YES! [うえはら]あさこ
|
|
86
|
+
|
|
87
|
+
うえはらあさこ contains あさこ ? => YES! うえはら[あさこ]
|
|
88
|
+
|
|
89
|
+
Double-sided match found! ==> Return immediately
|
|
80
90
|
```
|
|
81
91
|
|
|
82
92
|
* Step 4: If match found, split names accordingly
|
|
@@ -86,22 +96,7 @@ The logic is as follows:
|
|
|
86
96
|
[うえはら]あさこ => うえはら あさこ
|
|
87
97
|
```
|
|
88
98
|
|
|
89
|
-
* Step 5: If match not found,
|
|
90
|
-
|
|
91
|
-
```
|
|
92
|
-
上原亜沙子 =>
|
|
93
|
-
|
|
94
|
-
上原亜沙子 => X
|
|
95
|
-
原亜沙子 => X
|
|
96
|
-
亜沙子 => あさこ
|
|
97
|
-
沙子 => さこ
|
|
98
|
-
子 => こ
|
|
99
|
-
|
|
100
|
-
上原[亜沙子] => 上原 亜沙子
|
|
101
|
-
うえはら[あさこ] => うえはら あさこ
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
* Step 6: If match still not found, return `nil`
|
|
99
|
+
* Step 5: If match still not found, return `nil`
|
|
105
100
|
|
|
106
101
|
|
|
107
102
|
## Rake Tasks
|
|
@@ -1,25 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
module Backend
|
|
3
|
-
module Memory
|
|
4
|
-
class Store
|
|
1
|
+
# frozen_string_literal: true
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
module JapaneseNames
|
|
4
|
+
module Backend
|
|
5
|
+
module Memory
|
|
6
|
+
# In-memory store of the Enamdict dictionary
|
|
7
|
+
class Store
|
|
8
|
+
class << self
|
|
9
|
+
# Public: Finds kanji and/or kana regex strings in the dictionary via
|
|
10
|
+
# a structured query interface.
|
|
11
|
+
#
|
|
12
|
+
# kanji - (String, Array) Value or array of values of the kanji name to match.
|
|
13
|
+
#
|
|
14
|
+
# Returns the dict entries as an Array of Arrays [[kanji, kana, flags], ...]
|
|
15
|
+
def find(kanji)
|
|
16
|
+
kanji = Array(kanji)
|
|
17
|
+
store.values_at(*kanji).reject(&:nil?).inject(&:+) || []
|
|
18
|
+
end
|
|
7
19
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
20
|
+
# Public: The memoized dictionary instance.
|
|
21
|
+
def store
|
|
22
|
+
@store ||= JapaneseNames::Util::Kernel.deep_freeze(
|
|
23
|
+
File.open(filepath, 'r:utf-8').each_with_object({}) do |line, hash|
|
|
24
|
+
ary = line.chop.split('|')
|
|
25
|
+
hash[ary[0]] ||= []
|
|
26
|
+
hash[ary[0]] << ary
|
|
27
|
+
end
|
|
28
|
+
)
|
|
29
|
+
end
|
|
14
30
|
|
|
15
|
-
|
|
31
|
+
private
|
|
16
32
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
33
|
+
# Internal: Returns the filepath to the enamdict.min file.
|
|
34
|
+
def filepath
|
|
35
|
+
File.join(JapaneseNames.root, 'bin/enamdict.min')
|
|
36
|
+
end
|
|
37
|
+
end
|
|
20
38
|
end
|
|
21
39
|
end
|
|
22
40
|
end
|
|
23
41
|
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module JapaneseNames
|
|
3
4
|
# Enumerated flags for the ENAMDICT file (http://www.csse.monash.edu.au/~jwb/enamdict_doc.html)
|
|
4
5
|
module Enamdict
|
|
5
|
-
NAME_PLACE = %i
|
|
6
|
-
NAME_PERSON = %i
|
|
7
|
-
NAME_SURNAME = %i
|
|
8
|
-
NAME_GIVEN_MALE = %i
|
|
9
|
-
NAME_GIVEN_FEMALE = %i
|
|
10
|
-
NAME_GIVEN_OTHER = %i
|
|
6
|
+
NAME_PLACE = %i[p].freeze # place-name (99,500)
|
|
7
|
+
NAME_PERSON = %i[u].freeze # person name, either given or surname, as-yet unclassified (139,000)
|
|
8
|
+
NAME_SURNAME = %i[s].freeze # surname (138,500)
|
|
9
|
+
NAME_GIVEN_MALE = %i[m].freeze # male given name (14,500)
|
|
10
|
+
NAME_GIVEN_FEMALE = %i[f].freeze # female given name (106,300)
|
|
11
|
+
NAME_GIVEN_OTHER = %i[g].freeze # given name, as-yet not classified by sex (64,600)
|
|
11
12
|
NAME_SURNAME_ANY = (NAME_PLACE | NAME_PERSON | NAME_SURNAME).freeze
|
|
12
|
-
NAME_GIVEN_ANY = (NAME_PERSON | NAME_GIVEN_MALE| NAME_GIVEN_FEMALE | NAME_GIVEN_OTHER).freeze
|
|
13
|
+
NAME_GIVEN_ANY = (NAME_PERSON | NAME_GIVEN_MALE | NAME_GIVEN_FEMALE | NAME_GIVEN_OTHER).freeze
|
|
13
14
|
NAME_ANY = (NAME_SURNAME_ANY | NAME_GIVEN_ANY).freeze
|
|
14
15
|
end
|
|
15
16
|
end
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module JapaneseNames
|
|
3
4
|
# Query interface for ENAMDICT
|
|
4
5
|
class Finder
|
|
5
|
-
|
|
6
6
|
# Hash opts
|
|
7
7
|
# - kanji: String kanji to match
|
|
8
8
|
# - kana: String kana to match
|
|
9
9
|
# - kanji: Array<Symbol> ENAMDICT flags to match
|
|
10
|
-
def find(
|
|
11
|
-
backend.find(
|
|
10
|
+
def find(*args)
|
|
11
|
+
backend.find(*args)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
private
|
|
15
15
|
|
|
16
16
|
# Internal: Builds regex criteria for name.
|
|
17
17
|
def backend
|
|
18
|
-
::JapaneseNames::Backend::Memory::
|
|
18
|
+
::JapaneseNames::Backend::Memory::Store
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module JapaneseNames
|
|
3
4
|
# Provides methods to split a full Japanese name strings into surname and given name.
|
|
4
5
|
class Splitter
|
|
5
|
-
|
|
6
6
|
# Given a kanji and kana representation of a name splits into to family/given names.
|
|
7
7
|
#
|
|
8
8
|
# The choice to prioritize family name is arbitrary. Further analysis is needed
|
|
@@ -11,37 +11,62 @@ module JapaneseNames
|
|
|
11
11
|
# Returns Array [[kanji_fam, kanji_giv], [kana_fam, kana_giv]] if there was a match.
|
|
12
12
|
# Returns nil if there was no match.
|
|
13
13
|
def split(kanji, kana)
|
|
14
|
-
|
|
14
|
+
return nil unless kanji && kana
|
|
15
|
+
kanji = kanji.strip
|
|
16
|
+
kana = kana.strip
|
|
17
|
+
|
|
18
|
+
# Partition kanji into candidate n-grams
|
|
19
|
+
kanji_ngrams = Util::Ngram.ngram_partition(kanji)
|
|
20
|
+
|
|
21
|
+
# Find all possible matches of all kanji n-grams in dictionary
|
|
22
|
+
dict = finder.find(kanji_ngrams.flatten.uniq)
|
|
23
|
+
|
|
24
|
+
first_lhs_match = nil
|
|
25
|
+
first_rhs_match = nil
|
|
26
|
+
kanji_ngrams.each do |kanji_pair|
|
|
27
|
+
lhs_dict = dict.select { |d| d[0] == kanji_pair[0] }
|
|
28
|
+
rhs_dict = dict.select { |d| d[0] == kanji_pair[1] }
|
|
29
|
+
|
|
30
|
+
lhs_match = detect_lhs(lhs_dict, kanji, kana)
|
|
31
|
+
rhs_match = detect_rhs(rhs_dict, kanji, kana)
|
|
32
|
+
|
|
33
|
+
return lhs_match if lhs_match && lhs_match == rhs_match
|
|
34
|
+
|
|
35
|
+
first_lhs_match ||= lhs_match
|
|
36
|
+
first_rhs_match ||= rhs_match
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# As a fallback, return single-sided match prioritizing surname match first
|
|
40
|
+
first_lhs_match || first_rhs_match
|
|
15
41
|
end
|
|
16
42
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def detect_lhs(dict, kanji, kana)
|
|
46
|
+
dict_match = dict.select { |d| match_kana_lhs(d, kana) }.sort_by { |m| m[1].size * -1 }.first
|
|
47
|
+
if dict_match
|
|
48
|
+
kana_match = match_kana_lhs(dict_match, kana)
|
|
49
|
+
return [[dict_match[0], Util::Ngram.mask_left(kanji, dict_match[0])],
|
|
50
|
+
[kana_match, Util::Ngram.mask_left(kana, kana_match)]]
|
|
25
51
|
end
|
|
26
52
|
end
|
|
27
|
-
alias :split_given :split_giv
|
|
28
53
|
|
|
29
|
-
def
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if match = dict.detect{|m| kana_match = kana[/\A#{hk m[1]}/]}
|
|
36
|
-
return [[match[0], Util::Ngram.mask_left(kanji, match[0])],[kana_match, Util::Ngram.mask_left(kana, kana_match)]]
|
|
54
|
+
def detect_rhs(dict, kanji, kana)
|
|
55
|
+
dict_match = dict.select { |d| match_kana_rhs(d, kana) }.sort_by { |m| m[1].size * -1 }.first
|
|
56
|
+
if dict_match
|
|
57
|
+
kana_match = match_kana_rhs(dict_match, kana)
|
|
58
|
+
return [[Util::Ngram.mask_right(kanji, dict_match[0]), dict_match[0]],
|
|
59
|
+
[Util::Ngram.mask_right(kana, kana_match), kana_match]]
|
|
37
60
|
end
|
|
38
61
|
end
|
|
39
|
-
alias :split_surname :split_sur
|
|
40
62
|
|
|
41
|
-
|
|
42
|
-
|
|
63
|
+
def match_kana_lhs(dict, kana)
|
|
64
|
+
kana[/\A#{hk dict[1]}/]
|
|
65
|
+
end
|
|
43
66
|
|
|
44
|
-
|
|
67
|
+
def match_kana_rhs(dict, kana)
|
|
68
|
+
kana[/#{hk dict[1]}\z/]
|
|
69
|
+
end
|
|
45
70
|
|
|
46
71
|
# Returns a regex string which matches both hiragana and katakana variations of a String.
|
|
47
72
|
def hk(str)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module JapaneseNames
|
|
4
|
+
module Util
|
|
5
|
+
# Provides extensions to Ruby kernel.
|
|
6
|
+
class Kernel
|
|
7
|
+
class << self
|
|
8
|
+
# Recursively freezes an object
|
|
9
|
+
def deep_freeze(object)
|
|
10
|
+
case object
|
|
11
|
+
when Hash
|
|
12
|
+
object.each_value { |v| deep_freeze(v) }
|
|
13
|
+
object.freeze
|
|
14
|
+
when Array
|
|
15
|
+
object.each { |j| deep_freeze(j) }
|
|
16
|
+
object.freeze
|
|
17
|
+
when String
|
|
18
|
+
object.freeze
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -1,46 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module JapaneseNames
|
|
2
|
-
module Util
|
|
4
|
+
module Util
|
|
5
|
+
# Provides methods for parsing Japanese name strings.
|
|
6
|
+
class Ngram
|
|
7
|
+
class << self
|
|
8
|
+
# Generates middle-out partition n-grams for a string
|
|
9
|
+
def ngram_partition(str)
|
|
10
|
+
size = str.size
|
|
11
|
+
spiral_partition_indexes(size).map do |i|
|
|
12
|
+
index_partition(str, i)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
3
15
|
|
|
4
|
-
|
|
5
|
-
|
|
16
|
+
# Partitions a string based on an index
|
|
17
|
+
def index_partition(str, i)
|
|
18
|
+
[str[0...i], str[i..-1]]
|
|
19
|
+
end
|
|
6
20
|
|
|
7
|
-
|
|
21
|
+
# Lists middle-out partition points for a given string length
|
|
22
|
+
def spiral_partition_indexes(size)
|
|
23
|
+
ary = []
|
|
24
|
+
last = size / 2
|
|
25
|
+
ary << last
|
|
26
|
+
(size - 2).times do |i|
|
|
27
|
+
last += (i + 1) * (-1)**i
|
|
28
|
+
ary << last
|
|
29
|
+
end
|
|
30
|
+
ary
|
|
31
|
+
end
|
|
8
32
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
33
|
+
# Masks a String from the left side and returns the remaining (right) portion of the String.
|
|
34
|
+
#
|
|
35
|
+
# Example: mask_left("abcde", "ab") #=> "cde"
|
|
36
|
+
def mask_left(str, mask)
|
|
37
|
+
str.gsub(/\A#{mask}/, '')
|
|
38
|
+
end
|
|
15
39
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# Given a String, returns an array of progressively smaller substrings anchored on the right side.
|
|
24
|
-
#
|
|
25
|
-
# Example: ngram_right("abcd") #=> ["abcd", "bcd", "cd", "d"]
|
|
26
|
-
def ngram_right(str)
|
|
27
|
-
(0...str.size).map{|i| str[i..-1]}
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Masks a String from the left side and returns the remaining (right) portion of the String.
|
|
31
|
-
#
|
|
32
|
-
# Example: mask_left("abcde", "ab") #=> "cde"
|
|
33
|
-
def mask_left(str, mask)
|
|
34
|
-
str.gsub(/^#{mask}/, '')
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Masks a String from the right side and returns the remaining (left) portion of the String.
|
|
38
|
-
#
|
|
39
|
-
# Example: mask_right("abcde", "de") #=> "abc"
|
|
40
|
-
def mask_right(str, mask)
|
|
41
|
-
str.gsub(/#{mask}$/, '')
|
|
40
|
+
# Masks a String from the right side and returns the remaining (left) portion of the String.
|
|
41
|
+
#
|
|
42
|
+
# Example: mask_right("abcde", "de") #=> "abc"
|
|
43
|
+
def mask_right(str, mask)
|
|
44
|
+
str.gsub(/#{mask}\z/, '')
|
|
45
|
+
end
|
|
42
46
|
end
|
|
43
47
|
end
|
|
44
48
|
end
|
|
45
49
|
end
|
|
46
|
-
end
|
data/lib/japanese_names.rb
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
|
2
4
|
|
|
3
5
|
require 'moji'
|
|
4
6
|
|
|
@@ -6,10 +8,11 @@ require 'japanese_names/version'
|
|
|
6
8
|
require 'japanese_names/enamdict'
|
|
7
9
|
require 'japanese_names/finder'
|
|
8
10
|
require 'japanese_names/splitter'
|
|
11
|
+
require 'japanese_names/util/kernel'
|
|
9
12
|
require 'japanese_names/util/ngram'
|
|
10
13
|
require 'japanese_names/backend/memory/store'
|
|
11
|
-
require 'japanese_names/backend/memory/finder'
|
|
12
14
|
|
|
15
|
+
# Root namespace for library
|
|
13
16
|
module JapaneseNames
|
|
14
17
|
def self.root
|
|
15
18
|
File.join(File.dirname(__FILE__), '../')
|
data/spec/config.yml
ADDED
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
---
|
|
2
|
+
:last_names:
|
|
3
|
+
- 青木 あおき
|
|
4
|
+
- 秋保 アキホ
|
|
5
|
+
- 阿部 あべ
|
|
6
|
+
- 新井 あらい
|
|
7
|
+
- 安藤 あんどう
|
|
8
|
+
- 池田 いけだ
|
|
9
|
+
- 石井 いしい
|
|
10
|
+
- 石川 いしかわ
|
|
11
|
+
- 石田 いしだ
|
|
12
|
+
- 伊藤 イトウ
|
|
13
|
+
- 伊藤 いとう
|
|
14
|
+
- 犬山 イヌヤマ
|
|
15
|
+
- 井上 いのうえ
|
|
16
|
+
- 今井 いまい
|
|
17
|
+
- 岩崎 いわさき
|
|
18
|
+
- 上田 うえだ
|
|
19
|
+
- 上野 うえの
|
|
20
|
+
- 上原 ウエハラ
|
|
21
|
+
- 内田 うちだ
|
|
22
|
+
- 遠藤 えんどう
|
|
23
|
+
- 太田 おおた
|
|
24
|
+
- 大塚 おおつか
|
|
25
|
+
- 大野 おおの
|
|
26
|
+
- 岡田 オカダ
|
|
27
|
+
- 岡田 おかだ
|
|
28
|
+
- 岡本 おかもと
|
|
29
|
+
- 小川 おがわ
|
|
30
|
+
- 小野 おの
|
|
31
|
+
- 加藤 かとう
|
|
32
|
+
- 金子 かねこ
|
|
33
|
+
- 河野 かわの
|
|
34
|
+
- 菊池 きくち
|
|
35
|
+
- 木村 きむら
|
|
36
|
+
- 工藤 くどう
|
|
37
|
+
- 熊澤 クマザワ
|
|
38
|
+
- 小島 こじま
|
|
39
|
+
- 後藤 ごとう
|
|
40
|
+
- 小早志 コバヤシ
|
|
41
|
+
- 小林 こばやし
|
|
42
|
+
- 小山 こやま
|
|
43
|
+
- 近藤 こんどう
|
|
44
|
+
- 斎藤 さいとう
|
|
45
|
+
- 斉藤 さいとう
|
|
46
|
+
- 堺 サカイ
|
|
47
|
+
- 酒井 さかい
|
|
48
|
+
- 堺 さかい
|
|
49
|
+
- 坂本 さかもと
|
|
50
|
+
- 桜井 さくらい
|
|
51
|
+
- 佐々木 ささき
|
|
52
|
+
- 佐藤 サトウ
|
|
53
|
+
- 佐藤 さとう
|
|
54
|
+
- 佐野 さの
|
|
55
|
+
- 柴田 しばた
|
|
56
|
+
- 島田 しまだ
|
|
57
|
+
- 清水 しみず
|
|
58
|
+
- 菅原 すがわら
|
|
59
|
+
- 杉山 すぎやま
|
|
60
|
+
- 鈴木 すずき
|
|
61
|
+
- 高木 たかぎ
|
|
62
|
+
- 高田 たかだ
|
|
63
|
+
- 高野 たかの
|
|
64
|
+
- 高橋 たかはし
|
|
65
|
+
- 竹内 たけうち
|
|
66
|
+
- 武田 たけだ
|
|
67
|
+
- 田中 タナカ
|
|
68
|
+
- 田中 たなか
|
|
69
|
+
- 谷口 たにぐち
|
|
70
|
+
- 田村 たむら
|
|
71
|
+
- 千葉 ちば
|
|
72
|
+
- 中川 なかがわ
|
|
73
|
+
- 中島 なかじま
|
|
74
|
+
- 中野 なかの
|
|
75
|
+
- 中村 ナカムラ
|
|
76
|
+
- 中村 なかむら
|
|
77
|
+
- 中山 なかやま
|
|
78
|
+
- 西村 にしむら
|
|
79
|
+
- 野口 のぐち
|
|
80
|
+
- 野村 のむら
|
|
81
|
+
- 橋本 はしもと
|
|
82
|
+
- 長谷川 はせがわ
|
|
83
|
+
- 濱田 ハマダ
|
|
84
|
+
- 林 はやし
|
|
85
|
+
- 原 はら
|
|
86
|
+
- 原田 はらだ
|
|
87
|
+
- 樋口 ヒグチ
|
|
88
|
+
- 平野 ひらの
|
|
89
|
+
- 福田 ふくだ
|
|
90
|
+
- 藤井 ふじい
|
|
91
|
+
- 藤田 ふじた
|
|
92
|
+
- 藤原 ふじわら
|
|
93
|
+
- 古川 ふるかわ
|
|
94
|
+
- 前田 まえだ
|
|
95
|
+
- 増田 ますだ
|
|
96
|
+
- 松井 まつい
|
|
97
|
+
- 松田 まつだ
|
|
98
|
+
- 松本 まつもと
|
|
99
|
+
- 丸山 まるやま
|
|
100
|
+
- 三浦 みうら
|
|
101
|
+
- 光野 ミツノ
|
|
102
|
+
- 宮崎 みやざき
|
|
103
|
+
- 宮本 みやもと
|
|
104
|
+
- 村上 むらかみ
|
|
105
|
+
- 村田 むらた
|
|
106
|
+
- 森 モリ
|
|
107
|
+
- 森 もり
|
|
108
|
+
- 森田 もりた
|
|
109
|
+
- 安田 ヤスダ
|
|
110
|
+
- 山口 やまぐち
|
|
111
|
+
- 山崎 やまさき
|
|
112
|
+
- 山崎 ヤマザキ
|
|
113
|
+
- 山下 やました
|
|
114
|
+
- 山田 やまだ
|
|
115
|
+
- 山本 やまもと
|
|
116
|
+
- 横山 よこやま
|
|
117
|
+
- 吉田 よしだ
|
|
118
|
+
- 和田 わだ
|
|
119
|
+
- 渡辺 わたなべ
|
|
120
|
+
- 渡部 わたなべ
|
|
121
|
+
|
|
122
|
+
:first_names:
|
|
123
|
+
- 愛 あい
|
|
124
|
+
- 愛子 あいこ
|
|
125
|
+
- 愛美 あいみ
|
|
126
|
+
- 愛莉 あいり
|
|
127
|
+
- 愛理 あいり
|
|
128
|
+
- 愛梨 あいり
|
|
129
|
+
- 葵 あおい
|
|
130
|
+
- 昭夫 あきお
|
|
131
|
+
- 明 あきら
|
|
132
|
+
- 明美 あけみ
|
|
133
|
+
- 亜佐子 アサコ
|
|
134
|
+
- 朝陽 あさひ
|
|
135
|
+
- 杏那 あな
|
|
136
|
+
- 雨夜 あまや
|
|
137
|
+
- 彩花 あやか
|
|
138
|
+
- 彩乃 あやの
|
|
139
|
+
- 彩美 あやみ
|
|
140
|
+
- 郁子 イクコ
|
|
141
|
+
- 郁子 いくこ
|
|
142
|
+
- 勇 いさむ
|
|
143
|
+
- 樹 いつき
|
|
144
|
+
- 梅子 うめこ
|
|
145
|
+
- 瑛太 えいた
|
|
146
|
+
- 愛美 えみ
|
|
147
|
+
- 恵美 えみ
|
|
148
|
+
- 恵里 エリ
|
|
149
|
+
- 修 おさむ
|
|
150
|
+
- 海斗 かいと
|
|
151
|
+
- 香 かおり
|
|
152
|
+
- 一樹 かずき
|
|
153
|
+
- 和子 かずこ
|
|
154
|
+
- 香澄 カスミ
|
|
155
|
+
- 霞 かすみ
|
|
156
|
+
- 和美 かずみ
|
|
157
|
+
- 和也 かずや
|
|
158
|
+
- 克己 かつみ
|
|
159
|
+
- 寛 かん
|
|
160
|
+
- 清 きよし
|
|
161
|
+
- 桐子 きりこ
|
|
162
|
+
- 久美子 くみこ
|
|
163
|
+
- 敬子 ケイコ
|
|
164
|
+
- 慶子 けいこ
|
|
165
|
+
- 恵介 けいすけ
|
|
166
|
+
- 健三 けんぞう
|
|
167
|
+
- 健太 けんた
|
|
168
|
+
- 剛 ごう
|
|
169
|
+
- 康平 こうへい
|
|
170
|
+
- 虎太郎 こたろう
|
|
171
|
+
- 心春 こはる
|
|
172
|
+
- 咲希 さき
|
|
173
|
+
- 咲良 さくら
|
|
174
|
+
- 桜 さくら
|
|
175
|
+
- サクラ さくら
|
|
176
|
+
- 貞子 さだこ
|
|
177
|
+
- 禎子 さだこ
|
|
178
|
+
- 幸子 サチコ
|
|
179
|
+
- 幸子 さちこ
|
|
180
|
+
- 皐 さつき
|
|
181
|
+
- 三郎 さぶろ
|
|
182
|
+
- 小夜 さや
|
|
183
|
+
- 小百合 さゆり
|
|
184
|
+
- 重子 しげこ
|
|
185
|
+
- 茂 しげる
|
|
186
|
+
- 静香 しずか
|
|
187
|
+
- 駿 しゅん
|
|
188
|
+
- 翔 しょう
|
|
189
|
+
- 翔太 しょうた
|
|
190
|
+
- 四郎 しろ
|
|
191
|
+
- 真 しん
|
|
192
|
+
- 真一 しんいち
|
|
193
|
+
- 進 すすむ
|
|
194
|
+
- 節子 せつこ
|
|
195
|
+
- 颯太 そうた
|
|
196
|
+
- 颯真 そうま
|
|
197
|
+
- 蒼空 そら
|
|
198
|
+
- 大雅 たいが
|
|
199
|
+
- 大輝 たいき
|
|
200
|
+
- 大樹 だいき
|
|
201
|
+
- 大輝 だいき
|
|
202
|
+
- 大輔 だいすけ
|
|
203
|
+
- 大地 だいち
|
|
204
|
+
- 貴子 タカコ
|
|
205
|
+
- 孝 たかし
|
|
206
|
+
- 匠 たくみ
|
|
207
|
+
- 拓也 たくや
|
|
208
|
+
- 丈夫 たけお
|
|
209
|
+
- 武 たけし
|
|
210
|
+
- 武 たける
|
|
211
|
+
- 正 ただし
|
|
212
|
+
- 千夏 ちなつ
|
|
213
|
+
- 千代 ちよ
|
|
214
|
+
- 千代子 ちよこ
|
|
215
|
+
- 翼 つばさ
|
|
216
|
+
- 剛 つよし
|
|
217
|
+
- 貞子 ていこ
|
|
218
|
+
- 徹男 テツオ
|
|
219
|
+
- 哲也 てつや
|
|
220
|
+
- 智子 ともこ
|
|
221
|
+
- 知美 トモミ
|
|
222
|
+
- 朋美 ともみ
|
|
223
|
+
- 知美 ともみ
|
|
224
|
+
- 直樹 なおき
|
|
225
|
+
- 直子 なおこ
|
|
226
|
+
- 直美 なおみ
|
|
227
|
+
- 夏希 なつき
|
|
228
|
+
- 七海 ななみ
|
|
229
|
+
- 望 ノゾミ
|
|
230
|
+
- 延 のぶ
|
|
231
|
+
- 法子 のりこ
|
|
232
|
+
- 華 はな
|
|
233
|
+
- 隼人 はやと
|
|
234
|
+
- 遥 はるか
|
|
235
|
+
- 大翔 はると
|
|
236
|
+
- 陽翔 はると
|
|
237
|
+
- 陽斗 はると
|
|
238
|
+
- 悠人 はると
|
|
239
|
+
- 春菜 はるな
|
|
240
|
+
- 悠真 はるま
|
|
241
|
+
- 瞳 ひとみ
|
|
242
|
+
- 陽菜 ひな
|
|
243
|
+
- 陽向 ひなた
|
|
244
|
+
- 陽太 ひなた
|
|
245
|
+
- 陽葵 ひまり
|
|
246
|
+
- 大樹 ひろき
|
|
247
|
+
- 弘子 ひろこ
|
|
248
|
+
- 寛 ひろし
|
|
249
|
+
- 大翔 ひろと
|
|
250
|
+
- 文子 ふみこ
|
|
251
|
+
- 紅子 べにこ
|
|
252
|
+
- 螢 ほたる
|
|
253
|
+
- 舞 まい
|
|
254
|
+
- 誠 まこと
|
|
255
|
+
- 真 まこと
|
|
256
|
+
- 正男 まさお
|
|
257
|
+
- 正博 まさひろ
|
|
258
|
+
- 雅美 マサミ
|
|
259
|
+
- 勝 まさる
|
|
260
|
+
- 愛菜 まな
|
|
261
|
+
- 学 まなぶ
|
|
262
|
+
- 愛美 マナミ
|
|
263
|
+
- 真美 まみ
|
|
264
|
+
- 真弓 まゆみ
|
|
265
|
+
- 美羽 みう
|
|
266
|
+
- 美咲 みさき
|
|
267
|
+
- 美智 ミチ
|
|
268
|
+
- 緑 みどり
|
|
269
|
+
- 美菜 みな
|
|
270
|
+
- 湊 みなと
|
|
271
|
+
- 実 みのる
|
|
272
|
+
- 美優 みゆ
|
|
273
|
+
- 心優 みゆ
|
|
274
|
+
- 芽生 めい
|
|
275
|
+
- 芽依 めい
|
|
276
|
+
- めぐみ メグミ
|
|
277
|
+
- 恵 めぐみ
|
|
278
|
+
- 萌 もえ
|
|
279
|
+
- 桃子 ももこ
|
|
280
|
+
- 大和 やまと
|
|
281
|
+
- 結愛 ゆあ
|
|
282
|
+
- 結衣 ゆい
|
|
283
|
+
- 優香 ゆうか
|
|
284
|
+
- 優太 ゆうた
|
|
285
|
+
- 雄大 ゆうだい
|
|
286
|
+
- 悠斗 ゆうと
|
|
287
|
+
- 優斗 ゆうと
|
|
288
|
+
- 悠人 ゆうと
|
|
289
|
+
- 優奈 ゆうな
|
|
290
|
+
- 結菜 ゆうな
|
|
291
|
+
- 悠真 ゆうま
|
|
292
|
+
- 之子 ユキコ
|
|
293
|
+
- 雪子 ゆきこ
|
|
294
|
+
- 豊 ゆたか
|
|
295
|
+
- 優月 ゆづき
|
|
296
|
+
- 結菜 ゆな
|
|
297
|
+
- 由美 ゆみ
|
|
298
|
+
- 由美子 ゆみこ
|
|
299
|
+
- 百合子 ゆりこ
|
|
300
|
+
- 洋子 ヨウコ
|
|
301
|
+
- 陽子 ようこ
|
|
302
|
+
- 陽太 ようた
|
|
303
|
+
- 陽子 よこ
|
|
304
|
+
- 義雄 よしお
|
|
305
|
+
- 良子 よしこ
|
|
306
|
+
- 陸 りく
|
|
307
|
+
- 莉子 りこ
|
|
308
|
+
- 龍之介 りゅうのすけ
|
|
309
|
+
- 涼 りょう
|
|
310
|
+
- 凛 りん
|
|
311
|
+
- 麗華 れいか
|
|
312
|
+
- 玲子 レイコ
|
|
313
|
+
- 蓮 れん
|
|
314
|
+
|
|
315
|
+
:skip:
|
|
316
|
+
- 青木 緑
|
|
317
|
+
- 石井 真
|
|
318
|
+
- 石井 延
|
|
319
|
+
- 石川 舞
|
|
320
|
+
- 石川 緑
|
|
321
|
+
- 石川 湊
|
|
322
|
+
- 今井 真
|
|
323
|
+
- 今井 延
|
|
324
|
+
- 上野 愛
|
|
325
|
+
- 上野 真
|
|
326
|
+
- 太田 舞
|
|
327
|
+
- 太田 湊
|
|
328
|
+
- 岡本 萌
|
|
329
|
+
- 小野 愛
|
|
330
|
+
- 小野 真
|
|
331
|
+
- 金子 萌
|
|
332
|
+
- 河野 愛
|
|
333
|
+
- 河野 真
|
|
334
|
+
- 小山 咲希
|
|
335
|
+
- 小山 真
|
|
336
|
+
- 小山 緑
|
|
337
|
+
- 小山 陸
|
|
338
|
+
- 近藤 康平
|
|
339
|
+
- 近藤 虎太郎
|
|
340
|
+
- 近藤 心春
|
|
341
|
+
- 酒井 真
|
|
342
|
+
- 酒井 延
|
|
343
|
+
- 坂本 萌
|
|
344
|
+
- 桜井 真
|
|
345
|
+
- 桜井 延
|
|
346
|
+
- 佐々木 杏那
|
|
347
|
+
- 佐々木 三郎
|
|
348
|
+
- 佐々木 四郎
|
|
349
|
+
- 佐々木 緑
|
|
350
|
+
- 佐々木 陽子
|
|
351
|
+
- 佐々木 莉子
|
|
352
|
+
- 佐野 愛
|
|
353
|
+
- 佐野 真
|
|
354
|
+
- 柴田 舞
|
|
355
|
+
- 柴田 湊
|
|
356
|
+
- 杉山 真
|
|
357
|
+
- 杉山 緑
|
|
358
|
+
- 杉山 陸
|
|
359
|
+
- 鈴木 緑
|
|
360
|
+
- 高野 愛
|
|
361
|
+
- 高野 真
|
|
362
|
+
- 竹内 匠
|
|
363
|
+
- 田中 延
|
|
364
|
+
- 田中 緑
|
|
365
|
+
- 田中 湊
|
|
366
|
+
- 中野 愛
|
|
367
|
+
- 中野 真
|
|
368
|
+
- 中山 真
|
|
369
|
+
- 中山 緑
|
|
370
|
+
- 中山 陸
|
|
371
|
+
- 橋本 萌
|
|
372
|
+
- 長谷川 杏那
|
|
373
|
+
- 長谷川 三郎
|
|
374
|
+
- 長谷川 四郎
|
|
375
|
+
- 長谷川 陽子
|
|
376
|
+
- 林 咲希
|
|
377
|
+
- 林 孝
|
|
378
|
+
- 原 咲希
|
|
379
|
+
- 原 延
|
|
380
|
+
- 原 法子
|
|
381
|
+
- 平野 愛
|
|
382
|
+
- 平野 真
|
|
383
|
+
- 藤井 真
|
|
384
|
+
- 藤井 延
|
|
385
|
+
- 藤田 舞
|
|
386
|
+
- 藤田 湊
|
|
387
|
+
- 藤原 延
|
|
388
|
+
- 藤原 法子
|
|
389
|
+
- 古川 舞
|
|
390
|
+
- 古川 緑
|
|
391
|
+
- 古川 湊
|
|
392
|
+
- 松井 真
|
|
393
|
+
- 松井 延
|
|
394
|
+
- 松本 萌
|
|
395
|
+
- 丸山 真
|
|
396
|
+
- 丸山 緑
|
|
397
|
+
- 丸山 陸
|
|
398
|
+
- 宮本 萌
|
|
399
|
+
- 村田 舞
|
|
400
|
+
- 村田 湊
|
|
401
|
+
- 森 亜佐子
|
|
402
|
+
- 森 貴子
|
|
403
|
+
- 森 克己
|
|
404
|
+
- 森 久美子
|
|
405
|
+
- 森 咲希
|
|
406
|
+
- 森 孝
|
|
407
|
+
- 森田 舞
|
|
408
|
+
- 森田 湊
|
|
409
|
+
- 山本 萌
|
|
410
|
+
- 横山 真
|
|
411
|
+
- 横山 緑
|
|
412
|
+
- 横山 陸
|
|
413
|
+
- 和田 咲希
|
|
414
|
+
- 和田 重子
|
|
415
|
+
- 和田 茂
|
|
416
|
+
- 和田 静香
|
|
417
|
+
- 和田 駿
|
|
418
|
+
- 和田 翔
|
|
419
|
+
- 和田 翔太
|
|
420
|
+
- 和田 四郎
|
|
421
|
+
- 和田 真
|
|
422
|
+
- 和田 真一
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.push File.expand_path('../../lib', __FILE__)
|
|
2
4
|
|
|
3
5
|
require 'rubygems'
|
|
4
6
|
require 'rspec'
|
|
7
|
+
require 'yaml'
|
|
5
8
|
require 'japanese_names'
|
|
6
9
|
|
|
7
10
|
RSpec.configure do |config|
|
|
8
11
|
config.mock_with :rspec
|
|
12
|
+
|
|
13
|
+
config.disable_monkey_patching!
|
|
9
14
|
end
|
data/spec/unit/finder_spec.rb
CHANGED
|
@@ -1,39 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require 'spec_helper'
|
|
4
4
|
|
|
5
|
+
RSpec.describe JapaneseNames::Finder do
|
|
5
6
|
subject { described_class.new }
|
|
6
7
|
|
|
7
8
|
describe '#find' do
|
|
8
|
-
|
|
9
9
|
it 'should match kanji only' do
|
|
10
|
-
result = subject.find(
|
|
11
|
-
result.
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it 'should match kana only' do
|
|
15
|
-
result = subject.find(kana: 'ならしま')
|
|
16
|
-
result.should eq [["樽島", "ならしま", "u"],
|
|
17
|
-
["奈良島", "ならしま", "s"],
|
|
18
|
-
["楢島", "ならしま", "s"],
|
|
19
|
-
["楢嶋", "ならしま", "s"]]
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'should match both kanji and kana only' do
|
|
23
|
-
result = subject.find(kanji: '楢二郎', kana: 'ならじろう')
|
|
24
|
-
result.should eq [["楢二郎", "ならじろう", "m"]]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'should match flags as String' do
|
|
28
|
-
result = subject.find(kana: 'ならしま', flags: 's')
|
|
29
|
-
result.should eq [["奈良島", "ならしま", "s"],
|
|
30
|
-
["楢島", "ならしま", "s"],
|
|
31
|
-
["楢嶋", "ならしま", "s"]]
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it 'should match flags as Array' do
|
|
35
|
-
result = subject.find(kana: 'ならしま', flags: ['u','g'])
|
|
36
|
-
result.should eq [["樽島", "ならしま", "u"]]
|
|
10
|
+
result = subject.find('外世子')
|
|
11
|
+
expect(result).to eq [%w[外世子 とよこ f]]
|
|
37
12
|
end
|
|
38
13
|
end
|
|
39
14
|
end
|
data/spec/unit/ngram_spec.rb
CHANGED
|
@@ -1,24 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require 'spec_helper'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
RSpec.describe JapaneseNames::Util::Ngram do
|
|
6
|
+
describe '#ngram_partition' do
|
|
7
|
+
it { expect(described_class.ngram_partition('abcd')).to eq [%w[ab cd], %w[abc d], %w[a bcd]] }
|
|
8
|
+
it { expect(described_class.ngram_partition('abcde')).to eq [%w[ab cde], %w[abc de], %w[a bcde], %w[abcd e]] }
|
|
7
9
|
end
|
|
8
10
|
|
|
9
|
-
describe '#
|
|
10
|
-
it { expect(described_class.
|
|
11
|
+
describe '#index_partition' do
|
|
12
|
+
it { expect(described_class.index_partition('abcde', 2)).to eq %w[ab cde] }
|
|
11
13
|
end
|
|
12
14
|
|
|
13
|
-
describe '#
|
|
14
|
-
it { expect(described_class.
|
|
15
|
+
describe '#spiral_partition_indexes' do
|
|
16
|
+
it { expect(described_class.spiral_partition_indexes(0)).to eq [0] }
|
|
17
|
+
it { expect(described_class.spiral_partition_indexes(1)).to eq [0] }
|
|
18
|
+
it { expect(described_class.spiral_partition_indexes(2)).to eq [1] }
|
|
19
|
+
it { expect(described_class.spiral_partition_indexes(3)).to eq [1, 2] }
|
|
20
|
+
it { expect(described_class.spiral_partition_indexes(4)).to eq [2, 3, 1] }
|
|
21
|
+
it { expect(described_class.spiral_partition_indexes(5)).to eq [2, 3, 1, 4] }
|
|
22
|
+
it { expect(described_class.spiral_partition_indexes(6)).to eq [3, 4, 2, 5, 1] }
|
|
23
|
+
it { expect(described_class.spiral_partition_indexes(7)).to eq [3, 4, 2, 5, 1, 6] }
|
|
24
|
+
it { expect(described_class.spiral_partition_indexes(8)).to eq [4, 5, 3, 6, 2, 7, 1] }
|
|
25
|
+
it { expect(described_class.spiral_partition_indexes(9)).to eq [4, 5, 3, 6, 2, 7, 1, 8] }
|
|
15
26
|
end
|
|
16
27
|
|
|
17
28
|
describe '#mask_left' do
|
|
18
|
-
it { expect(described_class.mask_left(
|
|
29
|
+
it { expect(described_class.mask_left('abcde', 'ab')).to eq 'cde' }
|
|
19
30
|
end
|
|
20
31
|
|
|
21
32
|
describe '#mask_right' do
|
|
22
|
-
it { expect(described_class.mask_right(
|
|
33
|
+
it { expect(described_class.mask_right('abcde', 'de')).to eq 'abc' }
|
|
23
34
|
end
|
|
24
35
|
end
|
data/spec/unit/splitter_spec.rb
CHANGED
|
@@ -1,50 +1,42 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
require 'spec_helper'
|
|
4
4
|
|
|
5
|
+
RSpec.describe JapaneseNames::Splitter do
|
|
5
6
|
subject { described_class.new }
|
|
6
7
|
|
|
7
8
|
describe '#split' do
|
|
9
|
+
config = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'config.yml'))
|
|
10
|
+
skip_list = config[:skip]
|
|
8
11
|
|
|
9
|
-
[
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
['秋保','郁子','アキホ','いくこ'],
|
|
14
|
-
['光野','亜佐子','ミツノ','アサコ'],
|
|
15
|
-
['熊澤','貴子','クマザワ','タカコ']].each do |kanji_fam, kanji_giv, kana_fam, kana_giv|
|
|
16
|
-
it "should parse #{kanji_fam+kanji_giv} #{kana_fam+kana_giv}" do
|
|
17
|
-
result = subject.split(kanji_fam+kanji_giv, kana_fam+kana_giv)
|
|
18
|
-
result.should eq [[kanji_fam, kanji_giv], [kana_fam, kana_giv]]
|
|
19
|
-
end
|
|
12
|
+
config[:last_names].each do |last_name|
|
|
13
|
+
config[:first_names].each do |first_name|
|
|
14
|
+
kanji_fam, kana_fam = last_name.split(' ')
|
|
15
|
+
kanji_giv, kana_giv = first_name.split(' ')
|
|
20
16
|
|
|
21
|
-
|
|
22
|
-
result = subject.split_giv(kanji_fam+kanji_giv, kana_fam+kana_giv)
|
|
23
|
-
result.should eq [[kanji_fam, kanji_giv], [kana_fam, kana_giv]]
|
|
24
|
-
end
|
|
17
|
+
next if skip_list.index("#{kanji_fam} #{kanji_giv}")
|
|
25
18
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
19
|
+
it "should parse #{kanji_fam + kanji_giv} #{kana_fam + kana_giv}" do
|
|
20
|
+
result = subject.split(kanji_fam + kanji_giv, kana_fam + kana_giv)
|
|
21
|
+
expect(result).to eq [[kanji_fam, kanji_giv], [kana_fam, kana_giv]]
|
|
22
|
+
end
|
|
29
23
|
end
|
|
30
24
|
end
|
|
31
25
|
|
|
32
|
-
[[
|
|
33
|
-
it "should return nil for invalid name #{kanji_fam+kanji_giv} #{kana_fam+kana_giv}" do
|
|
34
|
-
result = subject.split(kanji_fam+kanji_giv, kana_fam+kana_giv)
|
|
35
|
-
result.
|
|
26
|
+
[%w[XXX XXX XXX XXX]].each do |kanji_fam, kanji_giv, kana_fam, kana_giv|
|
|
27
|
+
it "should return nil for invalid name #{kanji_fam + kanji_giv} #{kana_fam + kana_giv}" do
|
|
28
|
+
result = subject.split(kanji_fam + kanji_giv, kana_fam + kana_giv)
|
|
29
|
+
expect(result).to eq nil
|
|
36
30
|
end
|
|
37
31
|
end
|
|
38
32
|
|
|
39
33
|
it 'should strip leading/trailing whitespace' do
|
|
40
|
-
subject.split(' 上原望 ', ' ウエハラノゾミ ').
|
|
41
|
-
subject.split_giv(' 上原望 ', ' ウエハラノゾミ ').should eq [['上原','望'],['ウエハラ','ノゾミ']]
|
|
42
|
-
subject.split_sur(' 上原望 ', ' ウエハラノゾミ ').should eq [['上原','望'],['ウエハラ','ノゾミ']]
|
|
34
|
+
expect(subject.split(' 上原望 ', ' ウエハラノゾミ ')).to eq [%w[上原 望], %w[ウエハラ ノゾミ]]
|
|
43
35
|
end
|
|
44
36
|
|
|
45
37
|
it 'should return nil for nil input' do
|
|
46
|
-
subject.split(nil, 'ウエハラノゾミ').
|
|
47
|
-
subject.split('上原望', nil).
|
|
38
|
+
expect(subject.split(nil, 'ウエハラノゾミ')).to eq nil
|
|
39
|
+
expect(subject.split('上原望', nil)).to eq nil
|
|
48
40
|
end
|
|
49
41
|
end
|
|
50
42
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: japanese_names
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Johnny Shields
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-11-01 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: moji
|
|
@@ -76,13 +76,14 @@ files:
|
|
|
76
76
|
- README.md
|
|
77
77
|
- bin/enamdict.min
|
|
78
78
|
- lib/japanese_names.rb
|
|
79
|
-
- lib/japanese_names/backend/memory/finder.rb
|
|
80
79
|
- lib/japanese_names/backend/memory/store.rb
|
|
81
80
|
- lib/japanese_names/enamdict.rb
|
|
82
81
|
- lib/japanese_names/finder.rb
|
|
83
82
|
- lib/japanese_names/splitter.rb
|
|
83
|
+
- lib/japanese_names/util/kernel.rb
|
|
84
84
|
- lib/japanese_names/util/ngram.rb
|
|
85
85
|
- lib/japanese_names/version.rb
|
|
86
|
+
- spec/config.yml
|
|
86
87
|
- spec/spec_helper.rb
|
|
87
88
|
- spec/unit/finder_spec.rb
|
|
88
89
|
- spec/unit/ngram_spec.rb
|
|
@@ -107,11 +108,12 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
107
108
|
version: '0'
|
|
108
109
|
requirements: []
|
|
109
110
|
rubyforge_project:
|
|
110
|
-
rubygems_version: 2.
|
|
111
|
+
rubygems_version: 2.6.11
|
|
111
112
|
signing_key:
|
|
112
113
|
specification_version: 4
|
|
113
114
|
summary: Tools for parsing japanese names
|
|
114
115
|
test_files:
|
|
116
|
+
- spec/config.yml
|
|
115
117
|
- spec/spec_helper.rb
|
|
116
118
|
- spec/unit/finder_spec.rb
|
|
117
119
|
- spec/unit/ngram_spec.rb
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
module JapaneseNames
|
|
2
|
-
module Backend
|
|
3
|
-
module Memory
|
|
4
|
-
class Finder
|
|
5
|
-
|
|
6
|
-
class << self
|
|
7
|
-
|
|
8
|
-
# Public: Finds kanji and/or kana regex strings in the dictionary via
|
|
9
|
-
# a structured query interface.
|
|
10
|
-
#
|
|
11
|
-
# opts - The Hash options used to match the dictionary (default: {}):
|
|
12
|
-
# kanji: Regex to match kanji name (optional)
|
|
13
|
-
# kana: Regex to match kana name (optional)
|
|
14
|
-
# flags: Flag or Array of flags to filter the match (optional)
|
|
15
|
-
#
|
|
16
|
-
# Returns the dict entries as an Array of Arrays [[kanji, kana, flags], ...]
|
|
17
|
-
def find(opts={})
|
|
18
|
-
return [] unless opts[:kanji] || opts[:kana]
|
|
19
|
-
kanji = name_regex opts.delete(:kanji)
|
|
20
|
-
kana = name_regex opts.delete(:kana)
|
|
21
|
-
flags = flags_regex opts.delete(:flags)
|
|
22
|
-
store.select do |row|
|
|
23
|
-
(!kanji || row[0] =~ kanji) && (!kana || row[1] =~ kana) && (!flags || row[2] =~ flags)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
private
|
|
28
|
-
|
|
29
|
-
def store
|
|
30
|
-
::JapaneseNames::Backend::Memory::Store.store
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# Internal: Builds regex criteria for name.
|
|
34
|
-
def name_regex(name)
|
|
35
|
-
case name
|
|
36
|
-
when String, Symbol then /\A#{name}\z/
|
|
37
|
-
when Array then /\A(?:#{name.join('|')})\z/
|
|
38
|
-
else nil
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
# Internal: Builds regex criteria for flags.
|
|
43
|
-
def flags_regex(flags)
|
|
44
|
-
case flags
|
|
45
|
-
when ::JapaneseNames::Enamdict::NAME_ANY then nil
|
|
46
|
-
when String, Symbol then /[#{flags}]/
|
|
47
|
-
when Array then /[#{flags.join}]/
|
|
48
|
-
else nil
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
|
-
end
|