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   60137 use utf8;
  3         4  
  3         12  
5              
6 3     3   517 use Moo;
  3         9759  
  3         12  
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   3 my ($self,$result1,$result2) = @_;
138              
139 2 100       4 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   35 my ($self,$string) = @_;
147              
148 32         26 my $match_index;
149             my $last_match;
150 32         49 my $result_list = [''];
151            
152 32         53 $string = uc($string);
153 32         45 $string =~ tr/A-Z//cd;
154            
155 32         68 while (length($string)) {
156             # Loop all rules
157 174         176 RULES: foreach my $rule (@RULES) {
158            
159             # Check if rule matches
160             #if ($string =~ s/^([AEIOUJY]{2})([AEIOU])//i) {
161              
162 16919 100       68793 if ($string =~ s/^$rule->[0]//) {
163             # Is Start of a string?
164 174 100       469 if ($result_list->[0] eq '') {
    100          
165 32         27 $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         28 $match_index = 2;
169             # Other situation
170             } else{
171 111         84 $match_index = 3;
172             }
173 174 100       268 unless (defined $rule->[$match_index]) {
174 57         46 undef $last_match;
175 57         110 last RULES;
176             }
177 117 100 100     235 last RULES if (defined($last_match) && $last_match eq $rule->[$match_index]);
178 111         96 $last_match = $rule->[$match_index];
179 111         129 $result_list = _add_result($result_list,$rule->[$match_index]);
180 111         218 last RULES;
181             }
182             }
183             }
184            
185 32         30 foreach my $result (@$result_list) {
186 38         57 $result .= '0' x (6-length $result);
187 38         41 $result = substr($result,0,6);
188             }
189              
190 32         70 return $result_list;
191             }
192              
193             sub _add_result {
194 111     111   74 my $result = shift;
195 111         72 my $rule = shift;
196              
197 111 50       134 return $result unless defined $rule;
198              
199 111 100       116 if (ref($rule) eq 'ARRAY') {
200 6         8 my $newresult = [];
201 6         9 foreach my $result_string (@$result) {
202 6         10 foreach my $rule_string (@$rule) {
203 12         20 push @$newresult,$result_string.$rule_string;
204             }
205             }
206 6         9 return $newresult;
207             } else {
208 105         108 foreach my $result_string (@$result) {
209 106         133 $result_string .= $rule;
210             }
211 105         125 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