File Coverage

blib/lib/Lingua/DE/Sentence.pm
Criterion Covered Total %
statement 46 56 82.1
branch 35 40 87.5
condition 21 24 87.5
subroutine 6 12 50.0
pod 7 7 100.0
total 115 139 82.7


line stmt bran cond sub pod time code
1             package Lingua::DE::Sentence;
2              
3             require 5.005_62;
4 1     1   1093 use strict;
  1         2  
  1         45  
5 1     1   5 use warnings;
  1         1  
  1         41  
6 1     1   1137 use locale;
  1         251  
  1         6  
7              
8 1     1   1403 use POSIX qw(locale_h);
  1         8887  
  1         7  
9             require Exporter;
10              
11             our @ISA = qw(Exporter);
12              
13             our @EXPORT_OK = qw( get_sentences get_acronyms set_acronyms add_acronyms
14             get_file_extensions set_file_extensions add_file_extensions);
15              
16             our %EXPORT_TAGS = ( 'all' => \@EXPORT_OK );
17              
18             our @EXPORT = qw(get_sentences);
19              
20             our $VERSION = '0.07';
21              
22             # will be filled with known german abbrevations
23             my %ABBREVIATIONS;
24             # will be filled with some known file extensions
25             my %FILE_EXTENSIONS;
26              
27             # contains "real" consonant sounds
28             # sch, ch, st, ss, ... are spoken as one sound, that's way ?> and the alternation
29             # bb, dd, ... are not so often, but often used in acronyms
30             my $CONSONANT = qr/
31             (?>ff|ll|sch|ch|st|ss|mm|nn|pp|rr|tt|ck|pf|
32             [bcdfghklmnpqrstvwxz])/x;
33              
34             # common vocals in german
35             my $VOCAL = qr/[aeouiäöü]/;
36              
37             # the characters that can be between sentences (chr(150) is a dash, chr(160) is a nonbreaking whitespace)
38             my $LEADING_SENTENCE_CHAR = '[\s'.chr(150).chr(160).'?!>\#\.\-\*]';
39              
40             # regexp for new lines (even DOS, or MAC - Mode)
41             my $NL = qr/(?>\r\n|\n|\r)/;
42              
43             # Characters which could be quotation marks (171 and 187 are << and >> as one character)
44             my $QUOTE = q{\"\'<>} . chr(171) . chr(187);
45              
46             # Punctation marks
47             my $PUNCT = q{\.!?};
48              
49             # Preloaded methods go here.
50              
51             sub get_sentences {
52             # Set german locale
53 1     1 1 3916 my $old_locale = setlocale(LC_CTYPE);
54 1         408 setlocale(LC_CTYPE, "de_DE");
55              
56 1         469 my ($text) = @_;
57 1         4 my @pos = ();
58 1         3 my @sentences;
59 1         2 my ($leading_chars,$sent,$rest);
60 1         3 my $last_pos = 0;
61 1         195 while ($text =~ m/ (?!\w) # Sentence-End not at word characters
62             (?:
63             # normal end of Sentence like .?!
64             [$PUNCT] # End of Sentence could be a punctation
65             (?![^\w\r\n]*[$PUNCT,]) # and not as the first of some punctations (incl. comma)
66             [$QUOTE()]* # possibly followed by a quotation mark or bracket
67             |
68             # or an empty line
69             (?=\s\s) # so there must be at least two whitespaces
70             (?=\s*?$NL \s*?$NL) # exact, two end of lines (perhaps with spaces)
71             |
72             \Z)/gsxo) # or end of file
73             {
74 701         8980 ($leading_chars,$sent)
75             = substr($text,$last_pos,-$last_pos+pos($text))
76             =~ /^($LEADING_SENTENCE_CHAR*)(.*)$/s;
77 701         1921 $rest = substr($text,pos($text),100);
78            
79             # fix empty sentences
80             # every sentence has to include anything
81 701 100       8982 $sent !~ m/\w/ && next;
82            
83             # check only special cases, if not at end of text or paragraph
84 408 100       1834 if ($rest =~ m/^(?!\s*?$NL\s*?$NL)\s*\S/so) {
85            
86             # fix bla bla" sagte er.
87             # in general it's a word followed by " or ' and followed by a lowercase word
88 296 100 100     1745 $sent =~ /[$QUOTE]$/o && $rest =~ m/^[$QUOTE()\s]*([[:lower:]])/o && next;
89            
90             # fix enumerations
91 293 100 66     994 $sent =~ /\W\.\.[$QUOTE\)]?$/o && $rest !~ /^(?:\s*$NL){2}/o && next;
92            
93             # Abbrevations
94             # these are lower-Case words of length 1 (in german always)
95             # or in Abbr.-List (ignoriers Lower/UpperCase)
96             # or consists of only consonants
97             # or ends too curious, that means 4 consonants at the end
98 290 100       10609 if ($sent =~ /([^\W\d]+)\.[$QUOTE\)]*?$/o) {
99 205 100       1153 length($1) == 1 and next;
100 177         343 $_ = lc($1);
101 177 100       1700 $ABBREVIATIONS{$_} and next;
102 157 100       903 /^$CONSONANT+$/o and next;
103 144 100       503 /^$VOCAL+$/o and next;
104 142 100       3522 /$CONSONANT{4,}$/o and next;
105             }
106              
107             # Ordinal-Numbers like 1., 2., ...
108             # I treat all numbers till 39 as ordinal
109             # plus the numbers ending on ..00
110 226 100 100     1914 $sent =~ /\d\.$/ && $sent =~ /(?
      66        
      66        
111             (($1 < 40) || (($_ = $1) =~ /00$/ and $_ != 1900 and $_ != 2000 and $_ != 2100)) && next;
112              
113             # Rational Numbers, IP-Numbers, Phonenumbers like 127.32.2345
114 218 100 100     1505 $sent =~ /\.$/ && $rest =~ /^\d/ && next;
115              
116             # Something like Domain-Adresses, URLs and so on
117 212 100       1015 $sent =~ m{ (?=[hfnmg])
118             (?:http|file|ftp|news|mailto|gopher)
119             ://
120             [\w\d\.\%\_\/\:\-]+
121             (?
122             }xm
123             && next;
124 198 100 100     1119 $rest =~ /^([[:lower:]][[:lower:]\d]*[\.\?:\/]?)+/o
125             && $sent =~ /([[:lower:]\d]+[\.\?:\/])+$/o && next;
126              
127             # fix something like: Ich muss mich auf verschiedene (!) Browser einrichten.
128 191 100       521 $sent =~ / \( [$QUOTE\.!?\)]+ $/xo && next;
129              
130             # fix filenames like "document1.doc"
131             # look in extension list or extension consists of consonants
132 188 100 100     1684 if ($sent =~ /\.$/ && $rest =~ /^(\w{1,4})\b/) {
133 2 50       30 $FILE_EXTENSIONS{$_ = lc($1)} && next;
134 0 0       0 /^$CONSONANT+$/o && next;
135             }
136             }
137 298         503 $last_pos = pos($text);
138 298         448 push @sentences, $sent;
139 298 50       8230 push @pos, [pos($text) - length($sent) => pos($text)] if wantarray;
140             }
141 1 50       17 return wantarray ? (\@sentences, \@pos) : \@sentences;
142              
143 0           setlocale(LC_CTYPE, $old_locale);
144             }
145              
146             sub get_acronyms {
147 0     0 1   return keys %ABBREVIATIONS;
148             }
149              
150             sub set_acronyms {
151 0     0 1   %ABBREVIATIONS = map {$_ => 1} @_;
  0            
152             }
153              
154             sub add_acronyms {
155 0     0 1   $ABBREVIATIONS{$_} = 1 foreach (@_);
156             }
157              
158             sub get_file_extensions {
159 0     0 1   return keys %FILE_EXTENSIONS;
160             }
161              
162             sub set_file_extensions {
163 0     0 1   %FILE_EXTENSIONS = map {$_ => 1} @_;
  0            
164             }
165              
166             sub add_file_extensions {
167 0     0 1   $FILE_EXTENSIONS{$_} = 1 foreach (@_);
168             }
169              
170             sub BEGIN {
171 1     1   6144 $ABBREVIATIONS{$_} = 1 foreach qw(
172             abb
173             abf
174             abg
175             abk
176             abs
177             abschn
178             abt
179             accel
180             adr
181             ahd
182             akk
183             al
184             ala
185             alas
186             angekl
187             angew
188             anh
189             ank
190             anm
191             antw
192             anw
193             ao
194             apl
195             apr
196             ariz
197             ark
198             ass
199             aufl
200             aug
201             aussch
202             az
203             bat
204             batt
205             battr
206             bd
207             begr
208             beif
209             beil
210             beisp
211             bem
212             bes
213             betr
214             bez
215             bf
216             bfn
217             bg
218             bgbl
219             bhf
220             bl
221             brosch
222             bsp
223             bspw
224             btl
225             btto
226             bttr
227             bz
228             bzw
229             ca
230             calif
231             cand
232             cf
233             co
234             col
235             colo
236             conn
237             cresc
238             crt
239             ct
240             cwt
241             dat
242             decbr
243             dd
244             decresc
245             del
246             delin
247             des
248             desgl
249             dez
250             dgl
251             di
252             dim
253             dipl
254             dir
255             diss
256             do
257             doz
258             dptr
259             dr
260             dres
261             dt
262             dto
263             dtzd
264             dz
265             ebd
266             ed
267             edd
268             eidg
269             eigtl
270             einschl
271             em
272             entw
273             erdg
274             erg
275             esq
276             etc
277             ev
278             evtl
279             ew
280             exc
281             excud
282             exkl
283             expl
284             exz
285             fa
286             febr
287             fec
288             ff
289             fl
290             fla
291             fol
292             fr
293             frdl
294             frhr
295             frl
296             fud
297             ga
298             gbl
299             geb
300             gebr
301             gef
302             gefl
303             gefr
304             gegr
305             geh
306             gen
307             geogr
308             gesch
309             gest
310             get
311             gez
312             ggf
313             gr
314             grad
315             grundlag
316             habil
317             hbf
318             hd
319             hg
320             hl
321             hll
322             hptst
323             hr
324             hrn
325             hrsg
326             hs
327             hss
328             ia
329             ib
330             ibd
331             id
332             ide
333             idg
334             ill
335             imp
336             impr
337             i
338             ii
339             iii
340             in
341             inc
342             incl
343             ind
344             inf
345             ing
346             inkl
347             inv
348             io
349             ir
350             it
351             iv
352             ix
353             jan
354             jb
355             jg
356             jgg
357             jh
358             jr
359             jun
360             kan
361             kans
362             kap
363             kart
364             kath
365             ken
366             kffr
367             kfm
368             kgl
369             kl
370             koll
371             komp
372             konj
373             kop
374             kr
375             krs
376             kt
377             kto
378             kv
379             ky
380             la
381             led
382             leg
383             lfd
384             lic
385             lim
386             liq
387             lit
388             ln
389             lnbd
390             lt
391             ltd
392             ltn
393             lz
394             ma
395             mag
396             mass
397             math
398             md
399             mdal
400             mgr
401             mhd
402             mi
403             mia
404             mich
405             mill
406             min
407             mio
408             miss
409             mlat
410             mlle
411             mlles
412             mm
413             mme
414             mmes
415             mnd
416             mo
417             mod
418             mrd
419             msgr
420             mskr
421             mss
422             mwst
423             nachf
424             nachm
425             nchf
426             nd
427             nebr
428             nev
429             nhd
430             nlat
431             nm
432             no
433             nom
434             nov
435             nr
436             nrn
437             obd
438             oblt
439             od
440             oh
441             okla
442             okt
443             op
444             oreg
445             pa
446             pag
447             part
448             pf
449             pfd
450             pinx
451             pkt
452             pl
453             plur
454             pos
455             pp
456             ppa
457             ppbd
458             prakt
459             prim
460             prof
461             prot
462             prov
463             rd
464             rec
465             ref
466             reform
467             reg
468             regt
469             resp
470             rev
471             rf
472             rfz
473             rgt
474             rhld
475             rit
476             riten
477             rp
478             s
479             sa
480             sc
481             schw
482             scil
483             sculps
484             se
485             sek
486             sel
487             sen
488             sept
489             sfr
490             sign
491             sing
492             sog
493             sost
494             sp
495             spvg
496             spvgg
497             ss
498             st
499             sta
500             stacc
501             std
502             sto
503             str
504             string
505             stud
506             sva
507             svw
508             taf
509             techn
510             ten
511             tenn
512             tex
513             theor
514             tit
515             tsd
516             uffz
517             ult
518             urspr
519             usf
520             usw
521             ut
522             v
523             var
524             vdt
525             verh
526             verm
527             vert
528             verw
529             verz
530             vgl
531             vi
532             vii
533             viii
534             vm
535             vogtl
536             vorm
537             vors
538             vp
539             vs
540             wg
541             wis
542             wwe
543             wwr
544             x
545             xi
546             xii
547             xiii
548             xiv
549             xv
550             xvi
551             xvii
552             xviii
553             xix
554             xx
555             zb
556             zhd
557             ziff
558             zs
559             zschr
560             ztr
561             zz
562             zzt
563             );
564              
565 1         74 $FILE_EXTENSIONS{$_} = 1 foreach qw(doc html txt ps gz zip tar pdf gif jpeg mp3 bmp tmp exe com bat
566             pl java c cc vbs pod pm phtml shtml dhtml php);
567             }
568              
569             __END__