Kinh nghiệm bắt regex các thông tin từ một hồ sơ xuất từ PDF
/** * Tạo một mảng ngoài để có thể bắt kiểu tốt hơn. Xem chi tiết: https://github.com/microsoft/TypeScript/issues/36029#issuecomment-571810506 */constinit=[["Tên KH",/(?<=Tên\sKH:\s).*(?=\sCMND)/s],["Giới tính",/(?<=Giới\stính:\s).*(?=\sNăm\ssinh)/],["Ngày sinh",/(?<=Năm\ssinh:\s).*(?=\s)/],["SĐT KH",/(?<=SĐT\sKH:\s)\d*(?=\s)/],["Tạm trú",/(?<=Đ\/c Tạm trú:\s).*/],["Hộ khẩu",/(?<=Đ\/c Hộ khẩu:\s).*/],["Làm việc",/(?<=Đ\/c Làm việc:\s).*/],/** Thông tin khoản vay */["Số HĐ",/(?<=Số\sHĐ:\s).*?(?=\s)/],["Sản phẩm",/(?<=Sản phẩm:\s).*?(?=\s)/],["Hạn thanh toán",/(?<=Hạn\sthanh\stoán:\s).*?(?=\s)/],["Ngày TT",/(?<=Ngày TT:\s).*?(?=\s)/],["Trạng thái",/(?<=Trạng thái:\s).*?(?=\s)/],/** Thông tin quá hạn */["Số ngày quá hạn",/(?<=Số\sngày\squá\shạn:\s).*?(?=\s)/],["Thanh toán gần nhất",/(?<=Thanh\stoán\sgần\snhất:\s).*/],["Lịch sử TT gần nhất",/(?<=Lịch\ssử\sTT\sgần\snhất:\s).*/],["Hạn mức thẻ hiện tại",/(?<=Hạn\smức\sthẻ\shiện\stại\s).*(?=\s)/],["Hạn mức thẻ cũ",/(?<=Hạn\smức\sthẻ\scũ\s).*(?=\s)/],["Khoản vay",/(?<=Khoản vay:\s).*(?=\sNgày ký)/],["POS FULL",/(?<=POS FULL:\s).*(?=\stất\stoán\shợp\sđồng)/],["Tiền lãi",/(?<=Tiền\slãi:\s).*(?=\s)/],["Lãi quá hạn",/(?<=Lãi\squá\shạn:\s).*(?=\s)/],["Tổng dư nợ phải thanh toán",/(?<=Tổng\sdư\snợ\sphải\sthanh\stoán:\s).*(?=\s)/],]asconst;typeTênTrường=typeofinit[number][0];constdanhMụcRegex:Map<TênTrường,RegExp>=newMap(init);constdsLỗi=["❌ Hồ sơ gốc ghi cụ thể là NULL","❌ Regex không tìm được kết quả","❌ Hồ sơ gốc không có trường này","❌ Hồ sơ không ghi dữ liệu",]asconst;exporttypeLỗi=typeofdsLỗi[number];exportfunctionlàLỗi(biến:string|number|Temporal.PlainDate|ThanhToánGầnNhất|ĐịaChỉ|Lỗi):biếnisLỗi{if(dsLỗi.includes(biếnasLỗi))returntrue;returnfalse;}exportfunctionlấyRaw(trường:string,hồSơ:string):string|Lỗi{// const regexTrường = new RegExp(trường.replaceAll(" ", "\\s"));// if (!regexTrường.test(hồSơ)) return {lỗi: "Hồ sơ gốc không có trường này"}constraw=(danhMụcRegex.get(trường)asRegExp).exec(hồSơ);if(!raw)returndsLỗi[1];if(raw[0].includes("NULL"))returndsLỗi[0];returnraw[0];}exportfunctionlọcTênKH(hồSơ:string){constraw=lấyRaw("Tên KH",hồSơ);if(typeofraw!=="string")returnraw;returnraw.replaceAll("\n"," ");}functionlọcGiớiTính(hồSơ:string){constraw=lấyRaw("Giới tính",hồSơ);if(typeofraw!=="string")returnraw;if(raw==="FEMALE")return"nữ";return"nam";}functionlọcNgàySinh(hồSơ:string){constraw=lấyRaw("Ngày sinh",hồSơ);if(typeofraw!=="string")returnraw;const[ngày,tháng,năm]=raw.split("/");returnnewTemporal.PlainDate(parseInt(năm),parseInt(tháng),parseInt(ngày));}functionlọcSĐT(hồSơ:string){constraw=lấyRaw("SĐT KH",hồSơ);if(typeofraw!=="string")returnraw;returnraw.slice(0,2)==="84"?raw.replace("84","0"):raw;}/** Thông tin khoản vay */functionlọcSốHĐ(hồSơ:string){returnlấyRaw("Số HĐ",hồSơ);}functionlọcSảnPhẩm(hồSơ:string){returnlấyRaw("Sản phẩm",hồSơ);}functionlọcKhoảnVay(hồSơ:string){constraw=lấyRaw("Khoản vay",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw.replaceAll(".",""));}functionlọcHạnThanhToán(hồSơ:string){constraw=lấyRaw("Hạn thanh toán",hồSơ);if(làLỗi(raw))returnraw;const[ngày,tháng,năm]=raw.split("/");returnnewTemporal.PlainDate(parseInt(năm),parseInt(tháng),parseInt(ngày));}functionlọcNgàyThanhToán(hồSơ:string){constraw=lấyRaw("Ngày TT",hồSơ);if(làLỗi(raw))returnraw;const[ngày,tháng,năm]=raw.split("/");returnnewTemporal.PlainDate(parseInt(năm),parseInt(tháng),parseInt(ngày));}functionlọcHạnMứcThẻCũ(hồSơ:string){constraw=lấyRaw("Hạn mức thẻ cũ",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw.replaceAll(".",""));}functionlọcHạnMứcThẻHiệnTại(hồSơ:string){constraw=lấyRaw("Hạn mức thẻ hiện tại",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw.replaceAll(".",""));}functionlọcTrạngThái(hồSơ:string){returnlấyRaw("Trạng thái",hồSơ);}/** Thông tin quá hạn */functionlọcSốNgàyQuáHạn(hồSơ:string){constraw=lấyRaw("Số ngày quá hạn",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw);}functionlọcTTGầnNhất(hồSơ:string):ThanhToánGầnNhất|Lỗi{letraw=lấyRaw("Thanh toán gần nhất",hồSơ);if(làLỗi(raw)){consttemp=lấyRaw("Lịch sử TT gần nhất",hồSơ);if(làLỗi(temp))returnraw;raw=temp;}if(!/\|\s/.test(rawasstring))return{sốTiền:0,thờiĐiểm:null};constsplittedRaw=(rawasstring).split(/(?<=\d)\s(?=20)/);const[rawThờiĐiểm,rawSốTiền]=splittedRaw[0].split(/\|\s/);constrawThờiĐiểmSplited=rawThờiĐiểm.split("/");letngày=1,tháng=1,năm=2024;if(rawThờiĐiểmSplited.length===2){tháng=parseInt(rawThờiĐiểmSplited[1]);năm=parseInt(rawThờiĐiểmSplited[0]);}elseif(rawThờiĐiểmSplited.length===3){ngày=parseInt(rawThờiĐiểmSplited[0]);tháng=parseInt(rawThờiĐiểmSplited[1]);năm=parseInt(rawThờiĐiểmSplited[2]);}return{sốTiền:parseInt(rawSốTiền.replaceAll(",","")),thờiĐiểm:newTemporal.PlainDate(năm,tháng,ngày),};}functionlọcPosFull(hồSơ:string){constraw=lấyRaw("POS FULL",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw.replaceAll(".",""));}functionlọcTổngDưNợ(hồSơ:string){constraw=lấyRaw("Tổng dư nợ phải thanh toán",hồSơ);if(typeofraw!=="string")returnraw;returnparseInt(raw.replaceAll(".",""));}functionlọcTiềnLãi(hồSơ:string){constrawTiềnLãi=lấyRaw("Tiền lãi",hồSơ);if(!làLỗi(rawTiềnLãi)){returnparseInt((rawTiềnLãiasstring).replaceAll(".",""));}else{constrawLãiQuáHạn=lấyRaw("Lãi quá hạn",hồSơ);if(!làLỗi(rawLãiQuáHạn))returnparseInt((rawLãiQuáHạnasstring).replaceAll(".",""));returnrawTiềnLãiasLỗi;}}exportinterfaceThôngTinTừHồSơ{tênKH:string|Lỗi;cccdCmnd?:string|Lỗi;sđt:string|Lỗi;giớiTính:"nam"|"nữ"|Lỗi;ngàySinh:Temporal.PlainDate|Lỗi;địaChỉTạmTrú:ĐịaChỉ|Lỗi;địaChỉThườngTrú:ĐịaChỉ|Lỗi;địaChỉLàmViệc:ĐịaChỉ|Lỗi;sốHĐ:string|Lỗi;sảnPhẩm:string|Lỗi;trạngThái:string|Lỗi;hạnThanhToán:Temporal.PlainDate|Lỗi;ngàyThanhToán:Temporal.PlainDate|Lỗi;posFull?:number|Lỗi;khoảnVay?:number|Lỗi;hạnMứcThẻCũ?:number|Lỗi;hạnMứcThẻHiệnTại?:number|Lỗi;sốNgàyQuáHạn?:number|Lỗi;tiềnLãi?:number|Lỗi;thanhToánGầnNhất?:ThanhToánGầnNhất|Lỗi;tổngDưNợ:number|Lỗi;}exportclassThôngTinTừHồSơ{constructor(hồSơ:string){return{tênKH:lọcTênKH(hồSơ),cccdCmnd:undefined,sđt:lọcSĐT(hồSơ),giớiTính:lọcGiớiTính(hồSơ),ngàySinh:lọcNgàySinh(hồSơ),địaChỉTạmTrú:lọcĐịaChỉ(hồSơ,"Tạm trú"),địaChỉThườngTrú:lọcĐịaChỉ(hồSơ,"Hộ khẩu"),địaChỉLàmViệc:lọcĐịaChỉ(hồSơ,"Làm việc"),sốHĐ:lọcSốHĐ(hồSơ),sảnPhẩm:lọcSảnPhẩm(hồSơ),trạngThái:lọcTrạngThái(hồSơ),hạnThanhToán:lọcHạnThanhToán(hồSơ),ngàyThanhToán:lọcNgàyThanhToán(hồSơ),hạnMứcThẻHiệnTại:lọcHạnMứcThẻHiệnTại(hồSơ),hạnMứcThẻCũ:lọcHạnMứcThẻCũ(hồSơ),posFull:lọcPosFull(hồSơ),khoảnVay:lọcKhoảnVay(hồSơ),tiềnLãi:lọcTiềnLãi(hồSơ),thanhToánGầnNhất:lọcTTGầnNhất(hồSơ),sốNgàyQuáHạn:lọcSốNgàyQuáHạn(hồSơ),tổngDưNợ:lọcTổngDưNợ(hồSơ),};}}