majles_rdf first commit

This commit is contained in:
ajokar 2025-05-21 21:04:05 +03:30
commit 61813a0f44
3 changed files with 1418 additions and 0 deletions

56
base_process.py Normal file
View File

@ -0,0 +1,56 @@
import pandas as pd
from text_normalizer import normalizer
import json
"""word_enter_charachters = {"^p","'^l'"}"""
def read_excel_file(file_path):
"""
Reads an Excel file and returns a list of dictionaries containing the data.
"""
data = pd.read_excel(file_path)
bime_json_list = []
count = 0
for row in data.itertuples():
if count == 102:
pass
radif = normalizer.normalize_qanon(row[1]).replace('.','')
if radif == "":
radif = bime_json_list[count-1]['radif']
qanon_title = normalizer.normalize_qanon(row[2]).replace('.','').replace('#!#',' ').strip()
if qanon_title == "":
qanon_title = bime_json_list[count-1]['qanon_title']
related = normalizer.normalize_qanon(row[3]).replace('.','')
if related == "":
related = bime_json_list[count-1]['related']
row_structure = {
"id": row[0],
"radif":radif,
"qanon_title": qanon_title,
"related": related,
"status": normalizer.normalize_qanon(row[4]).replace('#!#',''),
"reasons": normalizer.normalize_qanon(row[5]).replace('#!#','\n'),
"description": normalizer.normalize_qanon(row[6]),
}
bime_json_list.append(row_structure)
count += 1
return bime_json_list
def write_to_json(data_dict, output_path):
"""
Writes data to a JSON file.
"""
with open(output_path, 'w', encoding='utf-8') as json_file:
json.dump(data_dict, json_file, indent=4, ensure_ascii=False)
return True
if __name__ == '__main__':
data_dict = read_excel_file('./data/bime.xlsx')
write_to_json(data_dict, './data/bime.json')
print('Done!')

1091
data/bime.json Normal file

File diff suppressed because it is too large Load Diff

271
text_normalizer.py Normal file
View File

@ -0,0 +1,271 @@
import re
class TextNormalizer:
def __init__(self, options=None):
self.options = options if options else {
"charArNormal": True,
"errorLine": True,
"alphabetsNormal": False,
"emptylinesNormal": False,
"hamzehNormal": False,
"spaceCorrection": False,
"trimLine": False
}
def split_words(self, text) :
if not text :
return []
### “”
words = re.split(r"[\t\n\r\.\'\"«»\)\(\]\[\{\}\%\#\$\*\<\>\/,;،؛ \-!?:٭؟]+", text)
return words
def normalize_qanon(self, text):
import pandas as pd
if pd.isna(text) or not text:
return ""
text = text.strip()
# اصلاح خطاهای متن در کد خط
text = text.replace("\\n", "\n")
text = text.replace("\\r", "\r")
text = re.sub(r"(\r\n)+", "\n", text)
text = text.replace("\r", "\n")
# یکسان سازی اختلاف حروف کیبوردهای مختلف - کدهای مختلف ولی نمایش یکسان
text = self.replace_alphabets(text)
# اعداد چسبیده به کلمات را با یک فاصله جدا می کند
text = self.word_digit_correction(text)
#فاصله های تکراری و خطوط خالی تکراری را یکی می کند
text = re.sub(r"( )+", " ", text)
text = re.sub(r"(\n)+", "\n", text)
# نرمال کردن حروف اختلافی عربی و فارسی
text = text.replace("ي", "ی")
text = text.replace("ك", "ک")
return text
def normalize_qanon_test(self, text):
if not text :
return ""
text = text.replace("\u00a0", " ") # No Break space
text = re.sub(r"\u200e|\u200f", " ", text) # LTR, RTL
text = self.word_digit_correction(text)
text = re.sub(r"( )+", " ", text)
text = self.space_correction(text)
text = self.heha_correction(text)
return text
def normalize_text(self, text):
if not text :
return ""
text = text.strip()
# اصلاح خطاهای متن در کد خط
if self.options.get("errorLine", False):
text = text.replace("\\n", "\n")
text = text.replace("\\r", "\r")
text = re.sub(r"(\r\n)+", "\n", text)
text = text.replace("\r", "\n")
# یکسان سازی اختلاف حروف کیبوردهای مختلف - کدهای مختلف ولی نمایش یکسان
if self.options.get("alphabetsNormal", False):
text = self.replace_alphabets(text)
# حذف خطوط و فاصله‌های خالی
if self.options.get("emptylinesNormal", False):
text = re.sub(r"( )+", " ", text)
text = re.sub(r"(\n)+", "\n", text)
# نرمال کردن حروف اختلافی عربی و فارسی
if self.options.get("charArNormal", True):
text = text.replace("ي", "ی")
text = text.replace("ك", "ک")
# پرش از اختلافات همزه‌ا
if self.options.get("hamzehNormal", False):
text = re.sub(r"ئ|ﺋ", "ی", text)
text = re.sub(r"ؤ|ﺅ", "و", text)
text = re.sub(r"ﺔ|ۀ|ة", "ه", text)
text = re.sub(r"إ|أ", "ا", text)
# اصلاح فاصله‌ها در ترکیب کلمات
if self.options.get("spaceCorrection", False):
text = self.space_correction(text)
# حذف خطوط اضافی اول و انتهای متن
if self.options.get("trimLine", False):
text = text.strip()
return text
def replace_alphabets(self, text):
if not text :
return ""
text = re.sub(r"\u200e|\u200f", " ", text) # LTR, RTL
text = re.sub(r"\u00AD|\u00AC", "\u200C", text) # نیم اسپیس خاص
text = re.sub(r"(\u002C)+", "\u200C", text) # نیم اسپیس تکراری
text = re.sub(r"ﺁ|آ", "آ", text)
text = re.sub(r"|ٱ|", "ا", text)
text = re.sub(r"ٲ|أ|ﺄ|ﺃ", "أ", text)
text = re.sub(r"ﺈ|ﺇ", "إ", text)
text = re.sub(r"ﺐ|ﺏ|ﺑ|ﺒ", "ب", text)
text = re.sub(r"ﭖ|ﭗ|ﭙ|ﭘ", "پ", text)
text = re.sub(r"ﭡ|ٺ|ٹ|ﭞ|ٿ|ټ|ﺕ|ﺗ|ﺖ|ﺘ", "ت", text)
text = re.sub(r"ﺙ|ﺛ|ﺚ|ﺜ", "ث", text)
text = re.sub(r"ﺝ|ڃ|ﺠ|ﺟ", "ج", text)
text = re.sub(r"ڃ|ﭽ|ﭼ", "چ", text)
text = re.sub(r"ﺢ|ﺤ|څ|ځ|ﺣ", "ح", text)
text = re.sub(r"ﺥ|ﺦ|ﺨ|ﺧ", "خ", text)
text = re.sub(r"ڏ|ډ|ﺪ|ﺩ", "د", text)
text = re.sub(r"ﺫ|ﺬ|ذ", "ذ", text)
text = re.sub(r"ڙ|ڗ|ڒ|ڑ|ڕ|ﺭ|ﺮ", "ر", text)
text = re.sub(r"ﺰ|ﺯ", "ز", text)
text = re.sub(r"", "ژ", text)
text = re.sub(r"ݭ|ݜ|ﺱ|ﺲ|ښ|ﺴ|ﺳ", "س", text)
text = re.sub(r"ﺵ|ﺶ|ﺸ|ﺷ", "ش", text)
text = re.sub(r"ﺺ|ﺼ|ﺻ|ﺹ", "ص", text)
text = re.sub(r"ﺽ|ﺾ|ﺿ|ﻀ", "ض", text)
text = re.sub(r"ﻁ|ﻂ|ﻃ|ﻄ", "ط", text)
text = re.sub(r"ﻆ|ﻇ|ﻈ", "ظ", text)
text = re.sub(r"ڠ|ﻉ|ﻊ|ﻋ|ﻌ", "ع", text)
text = re.sub(r"ﻎ|ۼ|ﻍ|ﻐ|ﻏ", "غ", text)
text = re.sub(r"ﻒ|ﻑ|ﻔ|ﻓ", "ف", text)
text = re.sub(r"ﻕ|ڤ|ﻖ|ﻗ|ﻘ", "ق", text)
text = re.sub(r"ڭ|ﻚ|ﮎ|ﻜ|ﮏ|ګ|ﻛ|ﮑ|ﮐ|ڪ|ك", "ک", text)
text = re.sub(r"ﮚ|ﮒ|ﮓ|ﮕ|ﮔ", "گ", text)
text = re.sub(r"ﻝ|ﻞ|ﻠ|ڵ|ﻟ", "ل", text)
text = re.sub(r"ﻵ|ﻶ|ﻷ|ﻸ|ﻹ|ﻺ|ﻻ|ﻼ", "لا", text)
text = re.sub(r"ﻡ|ﻤ|ﻢ|ﻣ", "م", text)
text = re.sub(r"ڼ|ﻦ|ﻥ|ﻨ|ﻧ", "ن", text)
text = re.sub(r"ވ|ﯙ|ۈ|ۋ|ﺆ|ۊ|ۇ|ۏ|ۅ|ۉ|ﻭ|ﻮ|ؤ", "و", text)
text = re.sub(r"|ھ||||ە|ہ", "ه", text)
text = re.sub(r"ﭛ|ﻯ|ۍ|ﻰ|ﻱ|ﻲ|ں|ﻳ|ﻴ|ﯼ|ې|ﯽ|ﯾ|ﯿ|ێ|ے|ى|ي", "ی", text)
text = re.sub(r"¬", "", text)
text = re.sub(r"•|·|●|·|・|∙|。|ⴰ", ".", text)
text = re.sub(r",|٬|٫|", "،", text)
text = re.sub(r"ʕ", "؟", text)
text = re.sub(r"”|“", "\"", text)
text = re.sub(r"۰|٠", "0", text)
text = re.sub(r"۱|١", "1", text)
text = re.sub(r"۲|٢", "2", text)
text = re.sub(r"۳|٣", "3", text)
text = re.sub(r"۴|٤", "4", text)
text = re.sub(r"۵", "5", text)
text = re.sub(r"۶|٦", "6", text)
text = re.sub(r"۷|٧", "7", text)
text = re.sub(r"۸|٨", "8", text)
text = re.sub(r"۹|٩", "9", text)
text = re.sub(r"²", "2", text)
text = re.sub(r"|ِ|ُ|َ|ٍ|ٌ|ً|", "", text)
text = re.sub(r'([\u0600-\u06FF])ـ([\u0600-\u06FF])', r'\1\2', text) # حذف حروف کشیده
return text
def date_correction(self, text):
# فرمت YYYY/MM/DD یا YYYY-MM-DD --> YYYY/MM/DD
text = re.sub(r'(\d{4})[\/\-](\d{1,2})[\/\-](\d{1,2})', r'\1/\2/\3', text)
# فرمت DD/MM/YYYY یا DD-MM-YYYY ---> YYYY/MM/DD
text = re.sub(r'(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})', r'\3/\2/\1', text)
def space_correction(self, text):
text = re.sub(r"^(بی|می|نمی)( )", r"\1", text)
text = re.sub(r"( )(می|نمی|بی)( )", r"\1\2", text)
text = re.sub(
r"( )(هایی|ها|های|ایی|هایم|هایت|هایش|هایمان|هایتان|هایشان|ات|ان|ین|انی|بان|ام|ای|یم|ید|اید|اند|بودم|بودی|بود|بودیم|بودید|بودند|ست)( )",
r"\2\3",
text,
)
# text = re.sub(r"( )(شده|نشده)( )", r"\2", text)
text = re.sub(
r"( )(طلبان|طلب|گرایی|گرایان|شناس|شناسی|گذاری|گذار|گذاران|شناسان|گیری|پذیری|بندی|آوری|سازی|بندی|کننده|کنندگان|گیری|پرداز|پردازی|پردازان|آمیز|سنجی|ریزی|داری|دهنده|آمیز|پذیری|پذیر|پذیران|گر|ریز|ریزی|رسانی|یاب|یابی|گانه|گانه‌ای|انگاری|گا|بند|رسانی|دهندگان|دار)( )",
r"\2\3",
text,
)
return text
# اعداد چسبیده به کلمات را با یک فاصله جدا می کند
def word_digit_correction(self, text):
text = re.sub(r"(\200C)(\d+)", r" \2", text)
text = re.sub(r"(\d+)(\200C)", r"\1 ", text)
text = re.sub(r"(\200C)([\t\n\r\.\'\"«»\)\(\]\[\{\}\#\$\*\<\>\/,;،؛ \-!?:٭؟])", r" \2", text)
text = re.sub(r"([\t\n\r\.\'\"«»\)\(\]\[\{\}\#\$\*\<\>\/,;،؛ \-!?:٭؟])(\200C)", r"\1 ", text)
# ## شماره22 -> شماره 22 22/ش2
# ### no ش/22 شد\22
# text = re.sub(r"([^\d \/\\]+?)(\d)", r"\1 \2", text)
# text = re.sub(r"(\d+)([^\d \/\\]+?)", r"\1 \2", text)
# ر54ر44ر135
text = re.sub(r"(\d+?)ر(\d+?)ر(\d+?)", r"\1\/\2\/\3", text)
text = re.sub(r"(\d+?)ر(\d+?)", r"\1\/\2", text)
# text = re.sub(r"(\w+)(\d+)", r"\1 \2", text)
# text = re.sub(r"(\d+)(\w+)", r"\1 \2", text)
return text
## رسیدگیها -> رسیدگی‌ها
def heha_correction(self, text):
text = re.sub(r"(ه)(ها )", r"\1\2", text)
text = re.sub(r"(ه)(های )", r"\1\2", text)
text = re.sub(r"(ی)(ها )", r"\1\2", text)
text = re.sub(r"(ی)(های )", r"\1\2", text)
return text
# # تست برنامه
# options = {
# "charArNormal": True, # نرمال کردن حروف عربی و فارسی
# "errorLine": True, # اصلاح خطاهای مربوط به خطوط و کاراکترها
# "alphabetsNormal": True, # نرمال‌سازی حروف
# "emptylinesNormal": True, # حذف فاصله‌های اضافی
# "hamzehNormal": True, # اصلاح همزه‌ها
# "spaceCorrection": True, # اصلاح فاصله‌ها در ترکیب کلمات
# "trimLine": True # حذف فضای خالی اضافی در ابتدا و انتهای متن
# }
normalizer = TextNormalizer()
# text = """
# سلام -- ـ ـ خوبی
# دادی ییی بی داد
# آیا ١٢۳۴۴۵۶۷٨ ، دادی یا ندادی؟
# ـ تغییرات جدید ٠۹۸٧٦٥٤٣٢١
# درباره‌ی ﻻ|ﻻ یا مثلا ﻷ صحبت کنیم.
# """
# text = """
# بند 2 ـ متن زير جايگزين ماده (17) قانون مي‌ شود و مواد (19)، (20) و (22) و مواد (27) تا (32) و تبصره‌ هاي آنها حذف مي ‌شوند:
# ماده 17 ـ اموال و دارايي ‌هايي كه در نتيجه فوت شخص اعم از فوت واقعي يا فرضي انتقال مي ‌يابد، به شرح زير مشمول ماليات است:
# 1 ـ نسبت به سپرده ‌هاي بانكي، اوراق مشاركت و ساير اوراق بهادار به ‌استثناي موارد مندرج در بند (2) اين ماده و سودهاي متعلق به آنها و همچنين سود سهام و سهم ‌الشركه تا تاريخ ثبت انتقال به نام وراث و يا پرداخت و تحويل به آنها به نرخ سه درصد (3 ٪)
# 2 ـ نسبت به سهام و سهم‌ الشركه و حق تقدم آنها يك و نيم (5 /1) برابر نرخهاي مذكور در تبصره (1) ماده (143) و ماده (143 مكرر) اين قانون طبق مقررات مزبور در تاريخ ثبت انتقال به نام وراث
# 3 ـ نسبت به حق ‌الامتياز و ساير اموال و حقوق مالي كه در بندهاي مذكور به آنها تصريح نشده است، به نرخ ده‌ درصد (10 ٪) ارزش روز در تاريخ تحويل يا ثبت انتقال به نام وراث
# 4 ـ نسبت به انواع وسايل نقليه موتوري، زميني، دريايي و هوايي به نرخ دو درصد (2 ٪) بهاي اعلامي توسط سازمان امور مالياتي كشور در تاريخ ثبت انتقال به نام وراث
# 5 ـ نسبت به املاك و حق واگذاري محل يك‌ و نيم (5 /1) برابر نرخهاي مذكور در ماده (59) اين قانون به مأخذ ارزش معاملاتي املاك و يا به مأخذ ارزش روز حق واگذاري حسب مورد، در تاريخ ثبت انتقال به نام وراث
# 6 ـ نسبت به اموال و دارايي ‌هاي متعلق به متوفاي ايراني كه در خارج از كشور واقع شده است پس از كسر ماليات بر ارثي كه از آن بابت به دولت محل وقوع اموال و دارايي ها پرداخت شده است به نرخ ده ‌درصد (10 ٪) ارزش ماترك كه مأخذ محاسبه ماليات بر ارث در كشور محل وقوع مال قرار گرفته است. در صورت عدم شمول ماليات بر ارث در كشور مزبور به مأخذ ارزش روز انتقال يا تحويل به نام وراث
# تبصره 1 ـ محاسبه و اخذ ماليات بر ارث در مورد متوفيان قبل از لازم ‌الاجراء شدن اين قانون (1 /1 /1395) اعم از اينكه پرونده مالياتي براي آنها تشكيل شده يا نشده باشد، مشمول حكم اين ماده نخواهد بود.
# تبصره 2 ـ نرخهاي مذكور در اين ماده مربوط به وراث طبقه اول است. در صورتي كه وراث طبقات دوم و سوم باشند، نرخهاي مذكور در اين ماده به ترتيب دو و چهار برابر خواهد شد.
# تبصره 3 ـ در صورتي كه متوفي و وراث، تبعه خارجي باشند، اموال و دارايي ‌هاي متوفي كه در ايران واقع است، مشمول ماليات به نرخ وراث طبقه اول خواهد بود.
# تبصره 4 ـ در مواردي كه وراث سهم خود از اموال موضوع بندهاي (2)، (4) و (5) اين ماده را به اشخاص ثالث يا وراث ديگر انتقال دهند، علاوه بر ماليات بر ارث به شرح اين فصل، مشمول ماليات طبق مقررات فصول مربوط خواهند بود.
# تبصره 5 ـ حقوق ناشي از عقود اجاره به شرط تمليك با بانكها و ساير نهادهاي مالي و اعتباري، نسبت به عرصه و اعيان املاك بر اساس ارزش معاملاتي در تاريخ ثبت انتقال به نام وراث محاسبه خواهد شد.
# """
# text="سلـام"
# text="46- متون زیر به عنوان تبصره‌ های ( 3 ) و ( 4 ) به ماده (-187-) قانون الحاق می ‌شود:"
# normalized_text = normalizer.normalize_qanon(text)
# print(normalized_text)