如何用正确的正则表达式条件提取银行交易信息



我的目的是读取一份银行文档,其中包含我当月的所有交易。今天,我在excel中手动输入所有交易。我想把它自动化。因此,今天下午,我试图阅读pdf并提取文本。

为此,我使用了pdf解析库。在文档上,交易行看起来像:

31-12-2019 Forfait 01-01-2019 - 31-12-2019 -29,00 // (loose money)  
31-12-2019 Forfait 01-01-2019 - 31-12-2019 50,00 // (win money)
31-12-2019 Mercedes -500,00 // (loose money) 
31-12-2019 Client 10 700,00 // (win money)

但有了pdf阅读器,我收到了:

31-12-2019Forfait 01-01-2019 - 31-12-2019-29,00
31-12-2019Forfait 01-01-2019 - 31-12-201950,00
31-12-2019Mercedes-500,00
31-12-2019Client10 700,00

我的目的是提取:日期-文本-金额

const transactions = data.text.split('n').filter(val => { 
// regex matching the transaction line of my pdf
});

我想用一些正则表达式来提取这个。但是我找不到正确的路。对于零散的钱,我们可以很容易地把它分开。然而,当交易为正时,很难检测到正确的金额,例如:

31-12-2019Forfait 01-01-2019 - 31-12-201950,00 
// expected {  date:31-12-2019  text: Forfait 01-01-2019 - 31-12-2019  amount: 50,00 }  
31-12-2019Client10 700,00
// expected { date:31-12-2019 text: Client amount: 10 700,00 }

我试过了:

(d{2}-d{2}-d{4})([a-zA-Z!@#%$&'()-`." ]+)([-?d ]*,[d]+)

但并没有涵盖我发现的每一个案例。通常,在描述中,您会在末尾添加数字。其他示例:

31-12-2019Comptoir1750,00
// expected 31-12-2019 Comptoir17 50,00

你知道吗?

非常感谢,

带有命名捕获组的正则表达式,如。。。(/^s*(?<date>d{2}-d{2}-d{4})s*(?<text>[^s-]+(?:(?:[s-]*d{2}-d{2}-d{4})+)?)s*(?<amount>-*d+,d+)/gm)。。。实现了一种基于…的方法。。。data.text.matchAll。。。

const data = { text: `31-12-2019Forfait 01-01-2019 - 31-12-2019-29,00
31-12-2019Forfait 01-01-2019 - 31-12-201950,00
31-12-2019Mercedes-500,00
31-12-2019Client10 700,00
31-12-2019Comptoir17 50,00` };
// see: [https://regex101.com/r/7TdghZ/1]
// const regXDataCaptures = (/^(?<date>[d-]+)s*(?<text>[^s-]+(?:(?:[s-]*d{2}-d{2}-d{4})+)?)s*(?<amount>-*d+,d+)/gm);
const regXDataCaptures = (/^s*(?<date>d{2}-d{2}-d{4})s*(?<text>[^s-]+(?:(?:[s-]*d{2}-d{2}-d{4})+)?)s*(?<amount>-*d+,d+)/gm);
const dataList = [
...data.text.matchAll(regXDataCaptures)
].map(({ groups }) => ({ ...groups }));
console.log('dataList :', dataList);
.as-console-wrapper { min-height: 100%!important; top: 0; }

为了避免过于复杂的表达(在理解和维护方面(,也为了不太容易受到边缘情况的影响,我个人更喜欢将这些过程划分为子任务,这些子任务可以一次更可靠地处理每个问题。

遵循这种方法的解决方案可能会使用两个正则表达式,如。。。CCD_ 4和CCD_。。。并且可能看起来与下一个提供的类似。。。

const data = { text: `31-12-2019Forfait 01-01-2019 - 31-12-2019-29,00
31-12-2019Forfait 01-01-2019 - 31-12-201950,00
31-12-2019Mercedes-500,00
31-12-2019 Client 10 700,00
31-12-2019Comptoir 17-50,00` };
// see: [https://regex101.com/r/Oj11JY/1/]
const regXCaptureDate = (/^s*(?<date>d{2}-d{2}-d{4})/);
// see: [https://regex101.com/r/LTgHd2/1/]
const regXCaptureAmount = (/(?:(?:[s-]*d{2}-d{2}-d{4})+)?s*(?<amount>-*d+,d+)s*$/);

function isNonEmptyStringValue(value) {
return ((typeof value === 'string') && (value !== ''));
}
function createAndCollectRecord(list, rawRecordItem) {
const record = {
...(regXCaptureDate.exec(rawRecordItem) || {}).groups,
...(regXCaptureAmount.exec(rawRecordItem) || {}).groups,
text: rawRecordItem
.replace(regXCaptureDate, '')
.replace(regXCaptureAmount, '')
.trim()
};
if (
['date', 'amount', 'text']
.every(key => isNonEmptyStringValue(record[key]))
) {
list.push(record);
}
return list;
}

const dataList = data.text
.split(/n/)
.reduce(createAndCollectRecord, []);
console.log('dataList :', dataList);
.as-console-wrapper { min-height: 100%!important; top: 0; }

这应该可以工作,它涵盖了您提供的所有案例。尽管我对这种方法持谨慎态度,因为它很脆弱,而且很容易与您在数据中尚未遇到的情况发生冲突。

https://regex101.com/r/tMbNPZ/1

^(d{1,2}-d{1,2}-d{2,4})(([wd]+s?d{2}-d{2}-d{4}]?s-sd{2}-d{2}-d{4})|([w]+))(([d,]+)|(s[d,]+)|(-[d,]+))

最新更新