File Coverage

blib/lib/Lingua/Stem/Cistem.pm
Criterion Covered Total %
statement 124 124 100.0
branch 32 32 100.0
condition 50 59 84.7
subroutine 10 10 100.0
pod 4 4 100.0
total 220 229 96.0


line stmt bran cond sub pod time code
1             package Lingua::Stem::Cistem;
2              
3 2     2   139225 use strict;
  2         15  
  2         56  
4 2     2   10 use warnings;
  2         4  
  2         56  
5              
6 2     2   14 use utf8;
  2         4  
  2         10  
7              
8 2     2   104 use 5.010001;
  2         8  
9              
10             require Exporter;
11              
12             BEGIN {
13 2     2   8 $Lingua::Stem::Cistem::VERSION = '0.05';
14 2         32 @Lingua::Stem::Cistem::ISA = qw(Exporter);
15 2         6 @Lingua::Stem::Cistem::EXPORT = qw();
16 2         4 @Lingua::Stem::Cistem::EXPORT_OK = qw(stem segment stem_robust segment_robust);
17 2         226 %Lingua::Stem::Cistem::EXPORT_TAGS = (
18             'all' => [qw(stem segment stem_robust segment_robust)],
19             'orig' => [qw(stem segment)],
20             'robust' => [qw(stem_robust segment_robust)],
21             );
22             }
23              
24             sub stem {
25 43   50 43 1 34941 my $word = shift // '';
26 43         70 my $case_insensitive = shift;
27              
28 43         99 my $upper = (ucfirst $word eq $word);
29              
30 43         76 $word = lc($word);
31 2     2   20 $word =~ tr/äöü/aou/;
  2         3  
  2         28  
  43         140  
32 43         119 $word =~ s/ß/ss/g;
33              
34 43         99 $word =~ s/^ge(.{4,})/$1/;
35              
36 43         74 $word =~ s/sch/\$/g;
37 43         74 $word =~ s/ei/\%/g;
38 43         70 $word =~ s/ie/\&/g;
39 43         150 $word =~ s/(.)\1/$1*/g;
40              
41 43         141 while(length($word)>3) {
42 28 100 66     276 if( length($word)>5 && ($word =~ s/e[mr]$// || $word =~ s/nd$//) ) {}
    100 66        
    100 100        
      100        
43             elsif( (!($upper) || $case_insensitive) && $word =~ s/t$//) {}
44             elsif( $word =~ s/[esn]$//) {}
45 17         32 else { last; }
46             }
47              
48 43         94 $word =~ s/(.)\*/$1$1/g;
49 43         63 $word =~ s/\$/sch/g;
50 43         72 $word =~ s/\%/ei/g;
51 43         77 $word =~ s/\&/ie/g;
52              
53 43         215 return $word;
54             }
55              
56             sub segment {
57 37   50 37 1 19490 my $word = shift // '';
58 37         57 my $case_insensitive = shift;
59              
60 37         83 my $upper = (ucfirst $word eq $word);
61              
62 37         79 $word = lc($word);
63              
64 37         58 my $original = $word;
65              
66 37         87 $word =~ s/sch/\$/g;
67 37         62 $word =~ s/ei/\%/g;
68 37         64 $word =~ s/ie/\&/g;
69 37         130 $word =~ s/(.)\1/$1*/g;
70              
71 37         56 my $suffix_length = 0;
72              
73 37         87 while(length($word)>3){
74 21 100 66     178 if( length($word)>5 && ($word =~ s/(e[mr])$// || $word =~ s/(nd)$//) ) {
    100 66        
    100 100        
      66        
75 3         8 $suffix_length += 2;
76             }
77             elsif( (!($upper) || $case_insensitive) && $word =~ s/t$//) {
78 5         14 $suffix_length++;
79             }
80             elsif( $word =~ s/([esn])$//) {
81 3         9 $suffix_length++;
82             }
83 10         19 else{ last; }
84             }
85              
86 37         66 $word =~ s/(.)\*/$1$1/g;
87              
88 37         57 $word =~ s/\$/sch/g;
89 37         54 $word =~ s/\%/ei/g;
90 37         51 $word =~ s/\&/ie/g;
91              
92 37         56 my $suffix = '';
93              
94 37 100       75 if( $suffix_length ) {
95 11         20 $suffix = substr($original, - $suffix_length);
96             }
97              
98 37         212 return ($word, $suffix);
99             }
100              
101             sub stem_robust {
102 51   50 51 1 27110 my $word = shift // '';
103 51         83 my $case_insensitive = shift;
104 51         77 my $keep_ge_prefix = shift;
105              
106 51         114 my $ucfirst = (ucfirst $word eq $word);
107              
108 51         119 $word = lc($word);
109 51         20809 $word =~ tr/äöü/aou/;
110 51         135 $word =~ s/([aou])\N{U+0308}/$1/g; # remove U+0308 COMBINING DIAERESIS
111 51         91 $word =~ s/ß/ss/g;
112              
113 51 100       121 $word =~ s/^ge(.{4,})/$1/ unless $keep_ge_prefix;
114              
115 51         87 $word =~ s/sch/\N{U+0006}/g; # \N{U+0006} ACK
116 51         74 $word =~ s/ei/\N{U+0007}/g; # \N{U+0007} BEL
117 51         77 $word =~ s/ie/\N{U+0008}/g; # \N{U+0008} BS
118              
119 51         171 $word =~ s/(.)\1/$1*/g;
120              
121 51         298 my @graphemes = $word =~ m/\X/g;
122 51         84 my $length = scalar @graphemes;
123             #my $length = scalar (($word =~ m/\X/g)); # does not work
124              
125 51         120 while($length > 3) {
126 32 100 100     290 if( $length>5 && ($word =~ s/e[mr]$// || $word =~ s/nd$//) ) {$length -= 2;}
  3 100 100     9  
    100 100        
      100        
127 5         15 elsif( (!($ucfirst) || $case_insensitive) && $word =~ s/t$//) {$length--;}
128 5         16 elsif( $word =~ s/[esn]$//) {$length--;}
129 19         36 else { last; }
130             }
131              
132 51         98 $word =~ s/(.)\*/$1$1/g;
133              
134 51         80 $word =~ s/\N{U+0006}/sch/g; # \N{U+0006} ACK
135 51         75 $word =~ s/\N{U+0007}/ei/g; # \N{U+0007} BEL
136 51         73 $word =~ s/\N{U+0008}/ie/g; # \N{U+0008} BS
137              
138 51         255 return $word;
139             }
140              
141              
142             sub segment_robust {
143 51   50 51 1 26523 my $word = shift // '';
144 51         88 my $case_insensitive = shift;
145 51         77 my $keep_ge_prefix = shift;
146              
147 51         116 my $ucfirst = (ucfirst $word eq $word);
148              
149 51         102 $word = lc($word);
150 51         160 $word =~ tr/äöü/aou/;
151 51         150 $word =~ s/([aou])\N{U+0308}/$1/g; # remove U+0308 COMBINING DIAERESIS
152 51         102 $word =~ s/ß/ss/g;
153              
154 51         76 my $prefix = '';
155 51 100 100     219 if (!$keep_ge_prefix && $word =~ s/^ge(.{4,})/$1/) {
156 2         4 $prefix = 'ge';
157             }
158              
159 51         86 my $original = $word;
160              
161 51         85 $word =~ s/sch/\N{U+0006}/g; # \N{U+0006} ACK
162 51         78 $word =~ s/ei/\N{U+0007}/g; # \N{U+0007} BEL
163 51         78 $word =~ s/ie/\N{U+0008}/g; # \N{U+0008} BS
164              
165 51         170 $word =~ s/(.)\1/$1*/g;
166              
167 51         303 my @graphemes = $word =~ m/\X/g;
168 51         81 my $length = scalar @graphemes;
169              
170 51         82 my $suffix_length = 0;
171              
172 51         122 while($length > 3){
173 32 100 100     304 if( $length > 5 && ($word =~ s/(e[mr])$// || $word =~ s/(nd)$//) ) {
    100 100        
    100 100        
      100        
174 3         8 $suffix_length += 2;
175 3         8 $length -= 2;
176             }
177             elsif( (!($ucfirst) || $case_insensitive) && $word =~ s/t$//) {
178 5         10 $suffix_length++;
179 5         13 $length--;
180             }
181             elsif( $word =~ s/([esn])$//) {
182 5         9 $suffix_length++;
183 5         11 $length--;
184             }
185 19         38 else{ last; }
186             }
187              
188 51         98 $word =~ s/(.)\*/$1$1/g;
189              
190 51         85 $word =~ s/\N{U+0006}/sch/g; # \N{U+0006} ACK
191 51         77 $word =~ s/\N{U+0007}/ei/g; # \N{U+0007} BEL
192 51         78 $word =~ s/\N{U+0008}/ie/g; # \N{U+0008} BS
193              
194 51         66 my $suffix = '';
195              
196 51 100       104 if( $suffix_length ) {
197 13         34 $suffix = substr($original, - $suffix_length);
198             }
199              
200 51         345 return ($prefix, $word, $suffix);
201             }
202              
203             1;
204             __END__