Spaces:
Running
Running
| import re | |
| from helpers.cleaner import clean_text | |
| # ----------- الأنماط (Regex Patterns) ----------- | |
| # المواد القانونية (مادة رقم ...) | |
| ARTICLE_PATTERN = re.compile( | |
| r"^\s*ماد[ةه]\s*[\(\s]*([0-9]+)[\)\s]*", | |
| re.IGNORECASE | re.UNICODE | |
| ) | |
| # الأقسام التقليدية (الباب / الفصل / القسم) | |
| SECTION_PATTERN = re.compile( | |
| r'^\s*(الباب|الفصل|القسم)\s+([^\n]+)', | |
| re.IGNORECASE | re.UNICODE | |
| ) | |
| # عبارة "أصدرنا القانون ..." داخل النص | |
| LAW_ISSUE_PATTERN = re.compile( | |
| r'أصدرنا القانون\s+(.*?)(?=\s{2,}|$)', | |
| re.IGNORECASE | re.UNICODE | |
| ) | |
| # ----------- تحويل الأرقام الهندية إلى عربية ----------- | |
| ARABIC_INDIC_DIGITS = str.maketrans("٠١٢٣٤٥٦٧٨٩", "0123456789") | |
| def normalize_digits(s: str) -> str: | |
| if not isinstance(s, str): | |
| return "" | |
| return s.translate(ARABIC_INDIC_DIGITS) | |
| # ----------- تنظيف النصوص ----------- | |
| def clean_text_block(text: str) -> str: | |
| if not isinstance(text, str): | |
| return "" | |
| return clean_text(normalize_digits(text.strip())) | |
| # ----------- دوال التعرف على نوع النص ----------- | |
| def is_article(text: str) -> bool: | |
| """هل السطر عبارة عن مادة قانونية؟""" | |
| if not isinstance(text, str): | |
| return False | |
| text_norm = normalize_digits(text) | |
| return bool(ARTICLE_PATTERN.match(text_norm)) | |
| def is_section(text: str) -> bool: | |
| """هل السطر عنوان قسم (باب / فصل / قسم)؟""" | |
| if not isinstance(text, str): | |
| return False | |
| text_norm = normalize_digits(text) | |
| return bool(SECTION_PATTERN.match(text_norm)) | |
| def detect_line_type(text: str) -> str: | |
| """ | |
| تحديد نوع السطر: | |
| - section → بداية قسم (باب/فصل/قسم) أو يحتوي «أصدرنا القانون» | |
| - article → بداية مادة | |
| - text → نص عادي | |
| """ | |
| if not isinstance(text, str) or not text.strip(): | |
| return "text" | |
| text_norm = normalize_digits(text) | |
| if SECTION_PATTERN.match(text_norm): | |
| return "section" | |
| if ARTICLE_PATTERN.match(text_norm): | |
| return "article" | |
| if LAW_ISSUE_PATTERN.search(text_norm): | |
| return "section" | |
| return "text" | |
| # ----------- استخراج تفاصيل القانون ----------- | |
| def extract_law_detail(text: str) -> str | None: | |
| """إرجاع التفاصيل التي تلي «أصدرنا القانون» مباشرة حتى نهاية السطر.""" | |
| if not isinstance(text, str): | |
| return None | |
| m = LAW_ISSUE_PATTERN.search(text) | |
| return m.group(1).strip() if m else None | |
| # ----------- استخراج رقم المادة ----------- | |
| def extract_article_number(text: str) -> int | None: | |
| """استخراج رقم المادة من النص إذا وجد.""" | |
| if not isinstance(text, str): | |
| return None | |
| text_norm = normalize_digits(text) | |
| m = ARTICLE_PATTERN.match(text_norm) | |
| if m: | |
| digits = re.match(r'(\d+)', m.group(1)) | |
| if digits: | |
| return int(digits.group(1)) | |
| return None |