File size: 1,677 Bytes
f592f80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
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
"""Conservative local sentence boundaries for prose, Arabic and Chinese punctuation.

This is punctuation-based segmentation, not a language model. Ambiguous abbreviations,
poetry and punctuation-free speech can require manual line breaks.
"""
import re

ABBREVIATIONS={'mr','mrs','ms','dr','prof','sr','jr','st','vs','etc','e.g','i.e','fig','no','vol','inc','ltd','a.m','p.m'}
CLOSERS='\"\'”’»))]}'


def split_sentences(text):
    paragraphs=re.split(r'\n[ \t]*\n+',text.replace('\r\n','\n').replace('\r','\n').strip())
    result=[]
    for paragraph in paragraphs:
        p=re.sub(r'[ \t]*\n[ \t]*',' ',paragraph).strip()
        start=0;i=0
        while i<len(p):
            ch=p[i]
            if ch not in '.!?؟。!?':i+=1;continue
            end=i+1
            while end<len(p) and p[end] in '.!?؟。!?':end+=1
            closing=end
            while closing<len(p) and p[closing] in CLOSERS:closing+=1
            if ch=='.':
                # Periods within decimals, addresses and abbreviations are not boundaries.
                if closing<len(p) and not p[closing].isspace():i=end;continue
                token=re.search(r'([\w.]+)\.$',p[:end])
                word=token.group(1) if token else ''
                if closing<len(p) and (word.casefold() in ABBREVIATIONS or re.fullmatch(r'(?:[A-Za-z]\.)*[A-Za-z]',word)):
                    i=end;continue
            # Chinese punctuation does not require a following space.
            segment=p[start:closing].strip()
            if segment:result.append(segment)
            start=closing;i=closing
        tail=p[start:].strip()
        if tail:result.append(tail)
    return result