File Coverage

blib/lib/Text/Phonetic/DaitchMokotoff.pm
Criterion Covered Total %
statement 44 44 100.0
branch 15 16 93.7
condition 3 3 100.0
subroutine 5 5 100.0
pod n/a
total 67 68 98.5


line stmt bran cond sub pod time code
1             # ============================================================================
2             package Text::Phonetic::DaitchMokotoff;
3             # ============================================================================
4 3     3   91302 use utf8;
  3         8  
  3         14  
5              
6 3     3   491 use Moo;
  3         8423  
  3         13  
7             extends qw(Text::Phonetic);
8              
9             __PACKAGE__->meta->make_immutable;
10              
11             our $VERSION = $Text::Phonetic::VERSION;
12              
13             our @RULES = (
14             ["SCHTSCH", 2, 4, 4],
15             ["SCHTSH", 2, 4, 4],
16             ["SCHTCH", 2, 4, 4],
17             ["SHTCH", 2, 4, 4],
18             ["SHTSH", 2, 4, 4],
19             ["STSCH", 2, 4, 4],
20             ["TTSCH", 4, 4, 4],
21             ["ZHDZH", 2, 4, 4],
22             ["SHCH", 2, 4, 4],
23             ["SCHT", 2, 43, 43],
24             ["SCHD", 2, 43, 43],
25             ["STCH", 2, 4, 4],
26             ["STRZ", 2, 4, 4],
27             ["STRS", 2, 4, 4],
28             ["STSH", 2, 4, 4],
29             ["SZCZ", 2, 4, 4],
30             ["SZCS", 2, 4, 4],
31             ["TTCH", 4, 4, 4],
32             ["TSCH", 4, 4, 4],
33             ["TTSZ", 4, 4, 4],
34             ["ZDZH", 2, 4, 4],
35             ["ZSCH", 4, 4, 4],
36             ["CHS", 5, 54, 54],
37             ["CSZ", 4, 4, 4],
38             ["CZS", 4, 4, 4],
39             ["DRZ", 4, 4, 4],
40             ["DRS", 4, 4, 4],
41             ["DSH", 4, 4, 4],
42             ["DSZ", 4, 4, 4],
43             ["DZH", 4, 4, 4],
44             ["DZS", 4, 4, 4],
45             ["SCH", 4, 4, 4],
46             ["SHT", 2, 43, 43],
47             ["SZT", 2, 43, 43],
48             ["SHD", 2, 43, 43],
49             ["SZD", 2, 43, 43],
50             ["TCH", 4, 4, 4],
51             ["TRZ", 4, 4, 4],
52             ["TRS", 4, 4, 4],
53             ["TSH", 4, 4, 4],
54             ["TTS", 4, 4, 4],
55             ["TTZ", 4, 4, 4],
56             ["TZS", 4, 4, 4],
57             ["TSZ", 4, 4, 4],
58             ["ZDZ", 2, 4, 4],
59             ["ZHD", 2, 43, 43],
60             ["ZSH", 4, 4, 4],
61             ["AI", 0, 1, undef],
62             ["AJ", 0, 1, undef],
63             ["AY", 0, 1, undef],
64             ["AU", 0, 7, undef],
65             ["CZ", 4, 4, 4],
66             ["CS", 4, 4, 4],
67             ["DS", 4, 4, 4],
68             ["DZ", 4, 4, 4],
69             ["DT", 3, 3, 3],
70             ["EI", 0, 1, undef],
71             ["EJ", 0, 1, undef],
72             ["EY", 0, 1, undef],
73             ["EU", 1, 1, undef],
74             ["IA", 1, undef, undef],
75             ["IE", 1, undef, undef],
76             ["IO", 1, undef, undef],
77             ["IU", 1, undef, undef],
78             ["KS", 5, 54, 54],
79             ["KH", 5, 5, 5],
80             ["MN", 66, 66, 66],
81             ["NM", 66, 66, 66],
82             ["OI", 0, 1, undef],
83             ["OJ", 0, 1, undef],
84             ["OY", 0, 1, undef],
85             ["PF", 7, 7, 7],
86             ["PH", 7, 7, 7],
87             ["SH", 4, 4, 4],
88             ["SC", 2, 4, 4],
89             ["ST", 2, 43, 43],
90             ["SD", 2, 43, 43],
91             ["SZ", 4, 4, 4],
92             ["TH", 3, 3, 3],
93             ["TS", 4, 4, 4],
94             ["TC", 4, 4, 4],
95             ["TZ", 4, 4, 4],
96             ["UI", 0, 1, undef],
97             ["UJ", 0, 1, undef],
98             ["UY", 0, 1, undef],
99             ["UE", 0, 1, undef],
100             ["ZD", 2, 43, 43],
101             ["ZH", 4, 4, 4],
102             ["ZS", 4, 4, 4],
103             ["RZ", [94,4], [94,4], [94,4]],
104             ["CH", [5,4], [5,4], [5,4]],
105             ["CK", [4,45], [4,45], [4,45]],
106             ["RS", [94,4], [94,4], [94,4]],
107             ["FB", 7, 7, 7],
108             ["A", 0, undef, undef],
109             ["B", 7, 7, 7],
110             ["D", 3, 3, 3],
111             ["E", 0, undef, undef],
112             ["F", 7, 7, 7],
113             ["G", 5, 5, 5],
114             ["H", 5, 5, undef],
115             ["I", 0, undef, undef],
116             ["K", 5, 5, 5],
117             ["L", 8, 8, 8],
118             ["M", 6, 6, 6],
119             ["N", 6, 6, 6],
120             ["O", 0, undef, undef],
121             ["P", 7, 7, 7],
122             ["Q", 5, 5, 5],
123             ["R", 9, 9, 9],
124             ["S", 4, 4, 4],
125             ["T", 3, 3, 3],
126             ["U", 0, undef, undef],
127             ["V", 7, 7, 7],
128             ["W", 7, 7, 7],
129             ["X", 5, 54, 54],
130             ["Y", 1, undef, undef],
131             ["Z", 4, 4, 4],
132             ["C", [5,4], [5,4], [5,4]],
133             ["J", [1,4], [4,undef], [4,undef]],
134             );
135              
136             sub _do_compare {
137 2     2   6 my ($self,$result1,$result2) = @_;
138              
139 2 100       8 return 50
140             if Text::Phonetic::_compare_list($result1,$result2);
141              
142 1         6 return 0;
143             }
144              
145             sub _do_encode {
146 32     32   69 my ($self,$string) = @_;
147              
148 32         55 my $match_index;
149             my $last_match;
150 32         70 my $result_list = [''];
151            
152 32         73 $string = uc($string);
153 32         69 $string =~ tr/A-Z//cd;
154            
155 32         89 while (length($string)) {
156             # Loop all rules
157 174         339 RULES: foreach my $rule (@RULES) {
158            
159             # Check if rule matches
160             #if ($string =~ s/^([AEIOUJY]{2})([AEIOU])//i) {
161              
162 16919 100       96665 if ($string =~ s/^$rule->[0]//) {
163             # Is Start of a string?
164 174 100       662 if ($result_list->[0] eq '') {
    100          
165 32         57 $match_index = 1;
166             # Before a vowel?
167             } elsif (Text::Phonetic::_is_inlist(substr($string,0,1),qw(A E I O U))) {
168 31         55 $match_index = 2;
169             # Other situation
170             } else{
171 111         153 $match_index = 3;
172             }
173 174 100       473 unless (defined $rule->[$match_index]) {
174 57         84 undef $last_match;
175 57         158 last RULES;
176             }
177 117 100 100     356 last RULES if (defined($last_match) && $last_match eq $rule->[$match_index]);
178 111         178 $last_match = $rule->[$match_index];
179 111         209 $result_list = _add_result($result_list,$rule->[$match_index]);
180 111         307 last RULES;
181             }
182             }
183             }
184            
185 32         56 foreach my $result (@$result_list) {
186 38         80 $result .= '0' x (6-length $result);
187 38         90 $result = substr($result,0,6);
188             }
189              
190 32         91 return $result_list;
191             }
192              
193             sub _add_result {
194 111     111   177 my $result = shift;
195 111         144 my $rule = shift;
196              
197 111 50       214 return $result unless defined $rule;
198              
199 111 100       219 if (ref($rule) eq 'ARRAY') {
200 6         12 my $newresult = [];
201 6         13 foreach my $result_string (@$result) {
202 6         12 foreach my $rule_string (@$rule) {
203 12         28 push @$newresult,$result_string.$rule_string;
204             }
205             }
206 6         13 return $newresult;
207             } else {
208 105         197 foreach my $result_string (@$result) {
209 106         193 $result_string .= $rule;
210             }
211 105         194 return $result;
212             }
213             }
214              
215             1;
216              
217             =encoding utf8
218              
219             =pod
220              
221             =head1 NAME
222              
223             Text::Phonetic::DaitchMokotoff - Daitch-Mokotoff algorithm
224              
225             =head1 DESCRIPTION
226              
227             Daitch-Mokotoff Soundex (D-M Soundex) is a phonetic algorithm invented in 1985
228             by genealogist Gary Mokotoff, and later improved by Randy Daitch, both of the
229             Jewish Genealogical Society. It is a refinement of the Russell and American
230             Soundex algorithms designed to allow matching of Slavic and Yiddish surnames
231             with similar pronunciation but differences in spelling. (Wikipedia, 2007)
232              
233             Some strings in the Daitch-Mokotoff algorithm produce ambigous results.
234             Therefore the results are always returned as Array references, even if there
235             is only a single result.
236              
237             =head1 AUTHOR
238              
239             Maroš Kollár
240             CPAN ID: MAROS
241             maros [at] k-1.com
242             http://www.k-1.com
243              
244             =head1 COPYRIGHT
245              
246             Text::Phonetic::Metaphone is Copyright (c) 2006,2007 Maroš. Kollár.
247             All rights reserved.
248              
249             This program is free software; you can redistribute
250             it and/or modify it under the same terms as Perl itself.
251              
252             The full text of the license can be found in the
253             LICENSE file included with this module.
254              
255             =head1 SEE ALSO
256              
257             Description of the algorithm can be found at
258             L
259              
260             L
261              
262             =cut