Spaces:
Sleeping
Sleeping
File size: 3,738 Bytes
bdc3fd6 | 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | """
Arabic Text Normalizer for Route Extraction Pipeline.
Handles:
- Hamza/Alif normalization
- Ta Marbuta/Ha equivalence
- Egyptian filler word removal
- Arabic prefix handling with landmark protection
- Whitespace normalization
"""
import re
# ============================================================
# Protected words that start with common prefix letters
# ============================================================
PROTECTED_PREFIXES = [
"لبنان", "لوران", "لوتس", "لوكاندة",
"بورسعيد", "بورفؤاد", "بني سويف", "بولاق", "بنها",
]
# ============================================================
# Egyptian noise/filler words to strip
# ============================================================
NOISE_PHRASES = [
"لو سمحت", "من فضلك", "يا ريس", "يا باشا", "يا حج",
"يا كابتن", "يا معلم", "يا عم", "الله يخليك",
"عايز اروح", "عايزة اروح", "محتاج اوصل",
"بسرعة", "دلوقتي", "ممكن", "خدني", "وصلني",
"عايزة", "عايز", "يعني", "كده", "بقى", "بالراحة",
"طب", "يلا", "بقولك", "اسمع", "شوف",
]
def normalize_arabic(text: str) -> str:
"""
Full Arabic text normalization pipeline.
Normalizes hamza variants, ta marbuta, diacritics, and whitespace.
Does NOT remove noise words (that's a separate step).
"""
if not text:
return ""
t = text.strip()
# Remove diacritics (tashkeel)
t = re.sub(r'[\u064B-\u065F\u0670]', '', t)
# Normalize Alif variants
t = t.replace('أ', 'ا').replace('إ', 'ا').replace('آ', 'ا')
# Normalize Alif Maqsura to Ya
t = t.replace('ى', 'ي')
# Normalize Ta Marbuta to Ha (for matching purposes)
# Note: We keep the original in the output, only normalize for matching
# t = t.replace('ة', 'ه') # Only used in matching, not preprocessing
# Normalize whitespace
t = re.sub(r'\s+', ' ', t).strip()
return t
def remove_noise(text: str) -> str:
"""Remove Egyptian filler/noise words from text."""
cleaned = text
for noise in NOISE_PHRASES:
cleaned = cleaned.replace(noise, '')
# Clean up extra whitespace
cleaned = re.sub(r'\s+', ' ', cleaned).strip()
return cleaned
def strip_prefixes(text: str) -> str:
"""
Strip Arabic definite article and preposition prefixes.
Protects known landmark names that naturally start with these letters.
"""
if not text:
return ""
cleaned = text.strip()
# Check if word is protected
for protected in PROTECTED_PREFIXES:
if cleaned.startswith(protected):
return cleaned
# Strip leading prepositions/articles: لل, لـ, ل, ب, ال
cleaned = re.sub(r'^(?:لل|لـ|ل|بـ|ب)(?![\s])', '', cleaned)
return cleaned.strip()
def normalize_for_matching(text: str) -> str:
"""
Aggressive normalization specifically for fuzzy matching.
Strips articles, normalizes ta marbuta, etc.
"""
if not text:
return ""
t = normalize_arabic(text)
# Strip definite article ال
t = re.sub(r'^ال', '', t)
# Normalize Ta Marbuta → Ha
t = t.replace('ة', 'ه')
# Remove common prefixes (شارع, ميدان, محطة)
t = re.sub(r'^(?:شارع|ميدان|محطة|موقف)\s*', '', t)
return t.strip()
def full_preprocess(text: str) -> str:
"""
Full preprocessing pipeline for incoming transcripts.
1. Normalize Arabic characters
2. Remove noise/filler words
3. Normalize whitespace
"""
t = normalize_arabic(text)
t = remove_noise(t)
return t
|