fin09
Deploy Bilingual Summarization NLP Suite with Git LFS
3d9ba5b
Raw History Blame Contribute Delete
3.96 kB
import re
from typing import List, Tuple
from .language_detector import LanguageDetector
from .arabic_preprocessor import ArabicPreprocessor
from .english_preprocessor import EnglishPreprocessor
class BilingualTokenizer:
"""
Unified Bilingual Tokenizer handling both Arabic and English sentence
and word level segmentation.
"""
# Protected English abbreviations to prevent erroneous sentence splitting
ABBREVIATIONS = r'(?:Dr|Mr|Mrs|Ms|Prof|Inc|Ltd|Corp|Co|e\.g|i\.e|vs|etc|Jan|Feb|Mar|Apr|Jun|Jul|Aug|Sep|Oct|Nov|Dec)'
def __init__(self):
self.lang_detector = LanguageDetector()
self.arabic_preprocessor = ArabicPreprocessor()
self.english_preprocessor = EnglishPreprocessor()
def split_sentences(self, text: str, lang: str = None) -> List[str]:
"""
Splits raw text into individual sentences while preserving
meaningful punctuation and handling abbreviations.
"""
if not text or not text.strip():
return []
if lang is None:
lang = self.lang_detector.detect_language(text)
# Standardize paragraph breaks
cleaned_text = re.sub(r'\r\n|\r', '\n', text)
cleaned_text = re.sub(r'\n+', '\n', cleaned_text)
# Handle sentence boundaries
if lang == 'ar':
# Arabic sentence delimiters: . ! ؟ ؛ \n
# Use regex looking for delimiters followed by space or newline or end of text
pattern = r'(?<=[\.\!\؟\؛\n])\s+'
raw_sentences = re.split(pattern, cleaned_text)
else:
# English sentence segmentation protecting abbreviations
# Protect abbreviations with temporary placeholder
temp_text = cleaned_text
abbr_matches = re.findall(rf'\b{self.ABBREVIATIONS}\.', temp_text, flags=re.IGNORECASE)
placeholder_map = {}
for i, abbr in enumerate(set(abbr_matches)):
placeholder = f"__ABBR_{i}__"
placeholder_map[placeholder] = abbr
temp_text = temp_text.replace(abbr, placeholder)
# English sentence delimiters: . ! ? \n
pattern = r'(?<=[\.\!\?\n])\s+'
raw_sentences = re.split(pattern, temp_text)
# Restore abbreviations
restored_sentences = []
for s in raw_sentences:
for placeholder, orig in placeholder_map.items():
s = s.replace(placeholder, orig)
restored_sentences.append(s)
raw_sentences = restored_sentences
# Final filtering of empty or whitespace-only sentences
sentences = [s.strip() for s in raw_sentences if s.strip() and len(s.strip()) > 5]
return sentences
def tokenize_words(self, text: str, lang: str = None, remove_stopwords: bool = False, stem: bool = False) -> List[str]:
"""
Tokenizes words with appropriate preprocessing for the detected or specified language.
"""
if lang is None:
lang = self.lang_detector.detect_language(text)
if lang == 'ar':
return self.arabic_preprocessor.tokenize_words(text, remove_stopwords=remove_stopwords, stem=stem)
else:
return self.english_preprocessor.tokenize_words(text, remove_stopwords=remove_stopwords, stem=stem)
def preprocess_sentence(self, sentence: str, lang: str = None, remove_stopwords: bool = True, stem: bool = False) -> str:
"""
Cleans and pre-processes a sentence string for vectorization/feature extraction.
"""
if lang is None:
lang = self.lang_detector.detect_language(sentence)
if lang == 'ar':
return self.arabic_preprocessor.preprocess_text(sentence, remove_stopwords=remove_stopwords, stem=stem)
else:
return self.english_preprocessor.preprocess_text(sentence, remove_stopwords=remove_stopwords, stem=stem)