| import spacy |
| import re |
| import unicodedata |
|
|
| class TextProcessor: |
| """ |
| Utilize spaCy NLP model to process text |
| """ |
| |
| def __init__(self): |
| self.nlp = spacy.load("en_core_web_sm") |
| self.document_filter = self.build_exclusion_pattern([ |
| 'chapter', |
| 'topic' |
| ]) |
|
|
| |
| self.GREEK_MAP = { |
| |
| 'Α': 'alpha', 'Β': 'beta', 'Γ': 'gamma', '∆': 'delta', 'Ε': 'epsilon', |
| 'Ζ': 'zeta', 'Η': 'eta', 'Θ': 'theta', 'Ι': 'iota', 'Κ': 'kappa', |
| 'Λ': 'lambda', 'Μ': 'mu', 'Ν': 'nu', 'Ξ': 'xi', 'Ο': 'omicron', |
| 'Π': 'pi', 'Ρ': 'rho', 'Σ': 'sigma', 'Τ': 'tau', 'Υ': 'upsilon', |
| 'Φ': 'phi', 'Χ': 'chi', 'Ψ': 'psi', 'Ω': 'omega', |
|
|
| |
| 'α': 'alpha', 'β': 'beta', 'γ': 'gamma', 'δ': 'delta', 'ε': 'epsilon', |
| 'ζ': 'zeta', 'η': 'eta', 'θ': 'theta', 'ι': 'iota', 'κ': 'kappa', |
| 'λ': 'lambda', 'μ': 'mu', 'ν': 'nu', 'ξ': 'xi', 'ο': 'omicron', |
| 'π': 'pi', 'ρ': 'rho', 'σ': 'sigma', 'ς': 'sigma', 'τ': 'tau', |
| 'υ': 'upsilon', 'φ': 'phi', 'χ': 'chi', 'ψ': 'psi', 'ω': 'omega' |
| } |
| self.GREEK_PATTERN = re.compile("|".join(map(re.escape, self.GREEK_MAP.keys()))) |
|
|
| def split_sentences(self, text: str): |
| """ |
| Function to split a paragraph into valid sentences |
| """ |
| doc = self.nlp(text) |
|
|
| ret = [] |
| for sent in doc.sents: |
| notrait_text = sent.text.strip() |
| if notrait_text and not self.document_filter.search(notrait_text): |
| ret.append(self.clean_text(notrait_text)) |
| |
| return ret |
| |
| def lemmatize(self, text: str): |
| """ |
| Function to reduce words inside a string into their base dictionary form |
| """ |
| |
| doc = self.nlp(text) |
| return " ".join([token.lemma_ for token in doc]) |
|
|
| def clean_text(self, text): |
| """ |
| Function to eliminate section strings |
| """ |
| |
| section_pattern = r"\b[IVXLCDM]+\.\s+[A-Z][A-Z\s]+\b" |
| return re.sub(section_pattern, "", text) |
| |
| def build_exclusion_pattern(self, keywords): |
| """ |
| Builder function for words filtering |
| """ |
| |
| |
| escaped = [re.escape(k) for k in keywords] |
| pattern = r"\b(" + "|".join(escaped) + r")\b" |
| return re.compile(pattern, re.IGNORECASE) |
| |
| def simplify_phrase(self, text: str): |
| """ |
| Function to simplify a phrase into its core structure using dependency parsing |
| """ |
| |
| |
| doc = self.nlp(text) |
| |
| |
| root = next((t for t in doc if t.dep_ == "ROOT"), None) |
| if not root: |
| return text |
|
|
| |
| parts = [root] |
| for child in root.children: |
| if child.dep_ in {"prep", "agent", "prt"}: |
| parts.append(child) |
|
|
| parts = sorted(parts, key=lambda x: x.i) |
| |
| return " ".join(t.text for t in parts) |
|
|
| def normalize_text(self, text: str) -> str: |
| """ |
| Canonical text normalization: |
| - Unicode normalize |
| - Expand Greek character into corresponding Latin term |
| - Remove spaces around hypens |
| - Replace hypen separators with spaces |
| - Normalize separators |
| - Remove unwanted symbols |
| - Collapse spaces |
| - Lowercase + strip |
| """ |
|
|
| text = unicodedata.normalize("NFKC", text) |
|
|
| |
| for k, v in self.GREEK_MAP.items(): |
| text = text.replace(k, v) |
|
|
| |
| text = re.sub(r"\s*-\s*", "-", text) |
|
|
| |
| text = re.sub(r"(?<=[a-zA-Z])-(?=[a-zA-Z])", " ", text) |
|
|
| |
| text = re.sub(r"[,+/]", " ", text) |
|
|
| |
| text = re.sub(r"[()\[\]\|]'", "", text) |
|
|
| |
| text = re.sub(r"\s+", " ", text) |
|
|
| return text.strip().lower() |
|
|
|
|
|
|
|
|
|
|
|
|