213 lines
15 KiB
Python
213 lines
15 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
import re
|
|
from typing import Iterable
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BankIdentity:
|
|
name: str
|
|
category: str
|
|
aliases: tuple[str, ...] = ()
|
|
ifsc_prefixes: tuple[str, ...] = ()
|
|
domains: tuple[str, ...] = ()
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class BankIdentityMatch:
|
|
name: str
|
|
category: str
|
|
confidence: float
|
|
evidence: tuple[str, ...]
|
|
|
|
|
|
# Commercial-bank identity registry. Parsing is intentionally independent of
|
|
# this list: templates extract transactions; this registry only assigns the
|
|
# institution name. The list covers current public/private banks, SFBs,
|
|
# payments banks, RRBs after the 2025 One-State-One-RRB amalgamation, major
|
|
# foreign banks operating in India, and legacy names that still appear in PDFs.
|
|
BANK_IDENTITIES: tuple[BankIdentity, ...] = (
|
|
# Public sector banks
|
|
BankIdentity("State Bank of India", "Public Sector Bank", ("STATE BANK OF INDIA", "SBI"), ("SBIN",), ("sbi.co.in", "onlinesbi.sbi")),
|
|
BankIdentity("Bank of Baroda", "Public Sector Bank", ("BANK OF BARODA", "BOB"), ("BARB",), ("bankofbaroda.in",)),
|
|
BankIdentity("Bank of India", "Public Sector Bank", ("BANK OF INDIA",), ("BKID",), ("bankofindia.co.in",)),
|
|
BankIdentity("Bank of Maharashtra", "Public Sector Bank", ("BANK OF MAHARASHTRA",), ("MAHB",), ("bankofmaharashtra.in",)),
|
|
BankIdentity("Canara Bank", "Public Sector Bank", ("CANARA BANK",), ("CNRB",), ("canarabank.com",)),
|
|
BankIdentity("Central Bank of India", "Public Sector Bank", ("CENTRAL BANK OF INDIA",), ("CBIN",), ("centralbankofindia.co.in",)),
|
|
BankIdentity("Indian Bank", "Public Sector Bank", ("INDIAN BANK",), ("IDIB",), ("indianbank.in",)),
|
|
BankIdentity("Indian Overseas Bank", "Public Sector Bank", ("INDIAN OVERSEAS BANK", "IOB"), ("IOBA",), ("iob.in",)),
|
|
BankIdentity("Punjab & Sind Bank", "Public Sector Bank", ("PUNJAB & SIND BANK", "PUNJAB AND SIND BANK"), ("PSIB",), ("punjabandsindbank.co.in",)),
|
|
BankIdentity("Punjab National Bank", "Public Sector Bank", ("PUNJAB NATIONAL BANK", "PNB"), ("PUNB",), ("pnbindia.in",)),
|
|
BankIdentity("UCO Bank", "Public Sector Bank", ("UCO BANK",), ("UCBA",), ("ucobank.com",)),
|
|
BankIdentity("Union Bank of India", "Public Sector Bank", ("UNION BANK OF INDIA",), ("UBIN",), ("unionbankofindia.co.in",)),
|
|
|
|
# Indian private sector banks
|
|
BankIdentity("Axis Bank", "Private Sector Bank", ("AXIS BANK",), ("UTIB",), ("axisbank.com",)),
|
|
BankIdentity("Bandhan Bank", "Private Sector Bank", ("BANDHAN BANK",), ("BDBL",), ("bandhanbank.com",)),
|
|
BankIdentity("CSB Bank", "Private Sector Bank", ("CSB BANK", "CATHOLIC SYRIAN BANK"), ("CSBK",), ("csb.co.in",)),
|
|
BankIdentity("City Union Bank", "Private Sector Bank", ("CITY UNION BANK",), ("CIUB",), ("cityunionbank.com",)),
|
|
BankIdentity("DCB Bank", "Private Sector Bank", ("DCB BANK", "DEVELOPMENT CREDIT BANK"), ("DCBL",), ("dcbbank.com",)),
|
|
BankIdentity("Dhanlaxmi Bank", "Private Sector Bank", ("DHANLAXMI BANK", "DHANALAKSHMI BANK"), ("DLXB",), ("dhanbank.com",)),
|
|
BankIdentity("Federal Bank", "Private Sector Bank", ("FEDERAL BANK",), ("FDRL",), ("federalbank.co.in",)),
|
|
BankIdentity("HDFC Bank", "Private Sector Bank", ("HDFC BANK",), ("HDFC",), ("hdfcbank.com",)),
|
|
BankIdentity("ICICI Bank", "Private Sector Bank", ("ICICI BANK",), ("ICIC",), ("icicibank.com",)),
|
|
BankIdentity("IDBI Bank", "Private Sector Bank", ("IDBI BANK",), ("IBKL",), ("idbibank.in",)),
|
|
BankIdentity("IDFC FIRST Bank", "Private Sector Bank", ("IDFC FIRST BANK", "IDFC BANK"), ("IDFB",), ("idfcfirstbank.com",)),
|
|
BankIdentity("IndusInd Bank", "Private Sector Bank", ("INDUSIND BANK",), ("INDB",), ("indusind.com",)),
|
|
BankIdentity("Jammu & Kashmir Bank", "Private Sector Bank", ("JAMMU & KASHMIR BANK", "JAMMU AND KASHMIR BANK", "J&K BANK"), ("JAKA",), ("jkb.bank.in", "jkbank.com")),
|
|
BankIdentity("Karnataka Bank", "Private Sector Bank", ("KARNATAKA BANK",), ("KARB",), ("karnatakabank.com",)),
|
|
BankIdentity("Karur Vysya Bank", "Private Sector Bank", ("KARUR VYSYA BANK", "KVB"), ("KVBL",), ("kvb.co.in",)),
|
|
BankIdentity("Kotak Mahindra Bank", "Private Sector Bank", ("KOTAK MAHINDRA BANK", "KOTAK BANK"), ("KKBK",), ("kotak.com",)),
|
|
BankIdentity("Nainital Bank", "Private Sector Bank", ("NAINITAL BANK",), ("NTBL",), ("nainitalbank.co.in",)),
|
|
BankIdentity("RBL Bank", "Private Sector Bank", ("RBL BANK", "RATNAKAR BANK"), ("RATN",), ("rblbank.com",)),
|
|
BankIdentity("South Indian Bank", "Private Sector Bank", ("SOUTH INDIAN BANK",), ("SIBL",), ("southindianbank.com",)),
|
|
BankIdentity("Tamilnad Mercantile Bank", "Private Sector Bank", ("TAMILNAD MERCANTILE BANK", "TMB"), ("TMBL",), ("tmb.in",)),
|
|
BankIdentity("YES Bank", "Private Sector Bank", ("YES BANK",), ("YESB",), ("yesbank.in",)),
|
|
|
|
# Small finance banks
|
|
BankIdentity("AU Small Finance Bank", "Small Finance Bank", ("AU SMALL FINANCE BANK",), ("AUBL",), ("aubank.in",)),
|
|
BankIdentity("Capital Small Finance Bank", "Small Finance Bank", ("CAPITAL SMALL FINANCE BANK",), ("CLBL",), ("capitalbank.co.in",)),
|
|
BankIdentity("Equitas Small Finance Bank", "Small Finance Bank", ("EQUITAS SMALL FINANCE BANK",), ("ESFB",), ("equitasbank.com",)),
|
|
BankIdentity("ESAF Small Finance Bank", "Small Finance Bank", ("ESAF SMALL FINANCE BANK",), ("ESMF",), ("esafbank.com",)),
|
|
BankIdentity("Jana Small Finance Bank", "Small Finance Bank", ("JANA SMALL FINANCE BANK",), ("JSFB",), ("janabank.com",)),
|
|
BankIdentity("Shivalik Small Finance Bank", "Small Finance Bank", ("SHIVALIK SMALL FINANCE BANK",), ("SMCB",), ("shivalikbank.com",)),
|
|
BankIdentity("slice Small Finance Bank", "Small Finance Bank", ("SLICE SMALL FINANCE BANK", "NORTH EAST SMALL FINANCE BANK"), ("NESF",), ("slice.bank",)),
|
|
BankIdentity("Suryoday Small Finance Bank", "Small Finance Bank", ("SURYODAY SMALL FINANCE BANK",), ("SURY",), ("suryodaybank.com",)),
|
|
BankIdentity("Ujjivan Small Finance Bank", "Small Finance Bank", ("UJJIVAN SMALL FINANCE BANK",), ("UJVN",), ("ujjivansfb.in",)),
|
|
BankIdentity("Unity Small Finance Bank", "Small Finance Bank", ("UNITY SMALL FINANCE BANK",), ("UNSF",), ("theunitybank.com",)),
|
|
BankIdentity("Utkarsh Small Finance Bank", "Small Finance Bank", ("UTKARSH SMALL FINANCE BANK",), ("UTKS",), ("utkarsh.bank",)),
|
|
|
|
# Payments banks
|
|
BankIdentity("Airtel Payments Bank", "Payments Bank", ("AIRTEL PAYMENTS BANK",), ("AIRP",), ("airtel.in/bank",)),
|
|
BankIdentity("Fino Payments Bank", "Payments Bank", ("FINO PAYMENTS BANK",), ("FINO",), ("finobank.com",)),
|
|
BankIdentity("India Post Payments Bank", "Payments Bank", ("INDIA POST PAYMENTS BANK", "IPPB"), ("IPOS",), ("ippbonline.com",)),
|
|
BankIdentity("Jio Payments Bank", "Payments Bank", ("JIO PAYMENTS BANK",), ("JIOP",), ("jiopaymentsbank.com",)),
|
|
BankIdentity("NSDL Payments Bank", "Payments Bank", ("NSDL PAYMENTS BANK",), ("NSPB",), ("nsdlpayments.bank",)),
|
|
BankIdentity("Paytm Payments Bank", "Payments Bank", ("PAYTM PAYMENTS BANK",), ("PYTM",), ("paytmbank.com",)),
|
|
|
|
# Regional Rural Banks after One-State-One-RRB (2025)
|
|
BankIdentity("Andhra Pradesh Grameena Bank", "Regional Rural Bank", ("ANDHRA PRADESH GRAMEENA BANK", "ANDHRA PRAGATHI GRAMEENA BANK", "CHAITANYA GODAVARI GRAMEENA BANK", "SAPTAGIRI GRAMEENA BANK"), ("UBIN0CG",), ("corebanking.apgb.in", "apgb.in")),
|
|
BankIdentity("Arunachal Pradesh Rural Bank", "Regional Rural Bank", ("ARUNACHAL PRADESH RURAL BANK",), (), ("apruralbank.com",)),
|
|
BankIdentity("Assam Gramin Bank", "Regional Rural Bank", ("ASSAM GRAMIN BANK", "ASSAM GRAMIN VIKASH BANK"), (), ("agvbank.co.in",)),
|
|
BankIdentity("Bihar Gramin Bank", "Regional Rural Bank", ("BIHAR GRAMIN BANK", "DAKSHIN BIHAR GRAMIN BANK", "UTTAR BIHAR GRAMIN BANK"), (), ("dbgb.in", "ubgb.in")),
|
|
BankIdentity("Chhattisgarh Gramin Bank", "Regional Rural Bank", ("CHHATTISGARH GRAMIN BANK", "CHHATTISGARH RAJYA GRAMIN BANK"), (), ("cgbank.in",)),
|
|
BankIdentity("Gujarat Gramin Bank", "Regional Rural Bank", ("GUJARAT GRAMIN BANK", "BARODA GUJARAT GRAMIN BANK", "SAURASHTRA GRAMIN BANK"), (), ("bggb.in", "sgbrrb.org")),
|
|
BankIdentity("Haryana Gramin Bank", "Regional Rural Bank", ("HARYANA GRAMIN BANK", "SARVA HARYANA GRAMIN BANK"), (), ("shgb.co.in",)),
|
|
BankIdentity("Himachal Pradesh Gramin Bank", "Regional Rural Bank", ("HIMACHAL PRADESH GRAMIN BANK",), (), ("hpgb.in",)),
|
|
BankIdentity("Jammu and Kashmir Grameen Bank", "Regional Rural Bank", ("JAMMU AND KASHMIR GRAMEEN BANK", "J&K GRAMEEN BANK", "ELLAQUAI DEHATI BANK"), (), ("jkgb.in",)),
|
|
BankIdentity("Jharkhand Rajya Gramin Bank", "Regional Rural Bank", ("JHARKHAND RAJYA GRAMIN BANK",), (), ("jrgb.in",)),
|
|
BankIdentity("Karnataka Grameena Bank", "Regional Rural Bank", ("KARNATAKA GRAMEENA BANK", "KARNATAKA GRAMIN BANK", "KARNATAKA VIKAS GRAMEENA BANK"), (), ("karnatakagraminbank.com", "kvgbank.com")),
|
|
BankIdentity("Kerala Gramin Bank", "Regional Rural Bank", ("KERALA GRAMIN BANK",), (), ("keralagbank.com",)),
|
|
BankIdentity("Madhya Pradesh Gramin Bank", "Regional Rural Bank", ("MADHYA PRADESH GRAMIN BANK", "MADHYANCHAL GRAMIN BANK"), (), ("mpgb.co.in",)),
|
|
BankIdentity("Maharashtra Gramin Bank", "Regional Rural Bank", ("MAHARASHTRA GRAMIN BANK", "VIDHARBHA KONKAN GRAMIN BANK"), (), ("mahagramin.in", "vkgb.co.in")),
|
|
BankIdentity("Manipur Rural Bank", "Regional Rural Bank", ("MANIPUR RURAL BANK",), (), ("manipurruralbank.com",)),
|
|
BankIdentity("Meghalaya Rural Bank", "Regional Rural Bank", ("MEGHALAYA RURAL BANK",), (), ("meghalayaruralbank.co.in",)),
|
|
BankIdentity("Mizoram Rural Bank", "Regional Rural Bank", ("MIZORAM RURAL BANK",), (), ("mizoramruralbank.in",)),
|
|
BankIdentity("Nagaland Rural Bank", "Regional Rural Bank", ("NAGALAND RURAL BANK",), (), ("nagalandruralbank.com",)),
|
|
BankIdentity("Odisha Grameen Bank", "Regional Rural Bank", ("ODISHA GRAMEEN BANK", "ODISHA GRAMYA BANK", "UTKAL GRAMEEN BANK"), (), ("odishabank.in", "odishagramyabank.in")),
|
|
BankIdentity("Puducherry Grama Bank", "Regional Rural Bank", ("PUDUCHERRY GRAMA BANK", "PUDUVAI BHARATHIAR GRAMA BANK"), (), ("puduvaibharathiargramabank.in",)),
|
|
BankIdentity("Punjab Gramin Bank", "Regional Rural Bank", ("PUNJAB GRAMIN BANK",), (), ("pgb.org.in",)),
|
|
BankIdentity("Rajasthan Gramin Bank", "Regional Rural Bank", ("RAJASTHAN GRAMIN BANK", "RAJASTHAN MARUDHARA GRAMIN BANK", "BARODA RAJASTHAN KSHETRIYA GRAMIN BANK"), (), ("rmgb.in", "brkgb.com")),
|
|
BankIdentity("Tamil Nadu Grama Bank", "Regional Rural Bank", ("TAMIL NADU GRAMA BANK",), (), ("tamilnadugramabank.com",)),
|
|
BankIdentity("Telangana Grameena Bank", "Regional Rural Bank", ("TELANGANA GRAMEENA BANK", "ANDHRA PRADESH GRAMEENA VIKAS BANK"), (), ("tgbhyd.in", "apgvbank.in")),
|
|
BankIdentity("Tripura Gramin Bank", "Regional Rural Bank", ("TRIPURA GRAMIN BANK",), (), ("tripuragraminbank.org",)),
|
|
BankIdentity("Uttar Pradesh Gramin Bank", "Regional Rural Bank", ("UTTAR PRADESH GRAMIN BANK", "ARYAVART BANK", "BARODA U.P. BANK", "BARODA UP BANK", "PRATHAMA U.P. GRAMIN BANK"), (), ("upgbank.com", "aryavart-rrb.com", "barodaupbank.in", "prathamaupbank.com")),
|
|
BankIdentity("Uttarakhand Gramin Bank", "Regional Rural Bank", ("UTTARAKHAND GRAMIN BANK",), (), ("uttarakhandgraminbank.com",)),
|
|
BankIdentity("West Bengal Gramin Bank", "Regional Rural Bank", ("WEST BENGAL GRAMIN BANK", "BANGIYA GRAMIN VIKASH BANK", "PASCHIM BANGA GRAMIN BANK", "UTTARBANGA KSHETRIYA GRAMIN BANK"), (), ("bgvb.in", "pbgbank.com", "ubkgb.org")),
|
|
|
|
# Foreign banks commonly issuing Indian account statements
|
|
BankIdentity("HSBC India", "Foreign Bank", ("HSBC BANK", "THE HONGKONG AND SHANGHAI BANKING CORPORATION"), ("HSBC",), ("hsbc.co.in",)),
|
|
BankIdentity("Standard Chartered Bank India", "Foreign Bank", ("STANDARD CHARTERED BANK",), ("SCBL",), ("sc.com/in",)),
|
|
BankIdentity("DBS Bank India", "Foreign Bank", ("DBS BANK INDIA", "DBS BANK"), ("DBSS",), ("dbs.com/in",)),
|
|
BankIdentity("Deutsche Bank India", "Foreign Bank", ("DEUTSCHE BANK",), ("DEUT",), ("deutschebank.co.in",)),
|
|
BankIdentity("Citibank India", "Foreign Bank", ("CITIBANK", "CITI BANK"), ("CITI",), ("citibank.co.in",)),
|
|
BankIdentity("Bank of America India", "Foreign Bank", ("BANK OF AMERICA",), ("BOFA",), ("bankofamerica.com",)),
|
|
BankIdentity("Barclays Bank India", "Foreign Bank", ("BARCLAYS BANK",), ("BARC",), ("barclays.in",)),
|
|
BankIdentity("BNP Paribas India", "Foreign Bank", ("BNP PARIBAS",), ("BNPA",), ("apac.bnpparibas",)),
|
|
BankIdentity("MUFG Bank India", "Foreign Bank", ("MUFG BANK", "BANK OF TOKYO-MITSUBISHI UFJ"), ("BOTM",), ("bk.mufg.jp",)),
|
|
BankIdentity("Mizuho Bank India", "Foreign Bank", ("MIZUHO BANK",), ("MHCB",), ("mizuhogroup.com",)),
|
|
BankIdentity("Sumitomo Mitsui Banking Corporation India", "Foreign Bank", ("SUMITOMO MITSUI BANKING CORPORATION", "SMBC"), ("SMBC",), ("smbc.co.jp",)),
|
|
)
|
|
|
|
|
|
def _normalise(value: str) -> str:
|
|
return re.sub(r"[^A-Z0-9.&]+", " ", str(value or "").upper()).strip()
|
|
|
|
|
|
def _alias_present(text_upper: str, alias: str) -> bool:
|
|
normalised_alias = _normalise(alias)
|
|
if not normalised_alias:
|
|
return False
|
|
return re.search(rf"(?<![A-Z0-9]){re.escape(normalised_alias)}(?![A-Z0-9])", text_upper) is not None
|
|
|
|
|
|
def detect_bank_identity(
|
|
text: str,
|
|
*,
|
|
ifsc: str = "",
|
|
source_file: str = "",
|
|
) -> BankIdentityMatch | None:
|
|
raw_text = str(text or "")
|
|
text_upper = _normalise(raw_text)
|
|
ifsc_upper = re.sub(r"[^A-Z0-9]", "", str(ifsc or "").upper())
|
|
file_upper = _normalise(Path(source_file or "").stem)
|
|
|
|
best: BankIdentityMatch | None = None
|
|
for bank in BANK_IDENTITIES:
|
|
score = 0.0
|
|
evidence: list[str] = []
|
|
|
|
# Longest/special IFSC prefixes carry the strongest identity signal.
|
|
matching_prefixes = [prefix for prefix in bank.ifsc_prefixes if ifsc_upper.startswith(prefix.upper())]
|
|
if matching_prefixes:
|
|
prefix = max(matching_prefixes, key=len)
|
|
score += 0.72 if len(prefix) > 4 else 0.58
|
|
evidence.append(f"IFSC prefix {prefix}")
|
|
|
|
for domain in bank.domains:
|
|
if domain.lower() in raw_text.lower():
|
|
score += 0.72
|
|
evidence.append(f"domain {domain}")
|
|
break
|
|
|
|
alias_hits = [alias for alias in bank.aliases if _alias_present(text_upper, alias)]
|
|
if alias_hits:
|
|
longest = max(alias_hits, key=len)
|
|
# Long formal headings are stronger than abbreviations such as SBI.
|
|
score += 0.72 if len(_normalise(longest)) >= 12 else 0.36
|
|
evidence.append(f"name {longest}")
|
|
|
|
if any(_alias_present(file_upper, alias) for alias in bank.aliases):
|
|
score += 0.10
|
|
evidence.append("filename")
|
|
|
|
confidence = min(score, 0.99)
|
|
if confidence < 0.50:
|
|
continue
|
|
candidate = BankIdentityMatch(bank.name, bank.category, confidence, tuple(dict.fromkeys(evidence)))
|
|
if best is None or candidate.confidence > best.confidence:
|
|
best = candidate
|
|
|
|
return best
|
|
|
|
|
|
def apply_detected_bank_identity(meta, df, text: str):
|
|
match = detect_bank_identity(
|
|
text,
|
|
ifsc=str(getattr(meta, "ifsc", "") or ""),
|
|
source_file=str(getattr(meta, "source_file", "") or ""),
|
|
)
|
|
if match is None:
|
|
return meta, df
|
|
|
|
# Do not let a reused layout/parser brand the statement as another bank.
|
|
# A high-confidence independent identity always wins.
|
|
if match.confidence >= 0.68:
|
|
meta.bank_name = match.name
|
|
if df is not None and not df.empty:
|
|
df = df.copy()
|
|
df["bank_name"] = match.name
|
|
return meta, df
|