适配多国酒店账单的供应商、时间、日期、货币正则表达式需求
多国酒店账单字段提取解决方案
现有酒店账单来自印度、西班牙等多个国家,当前正则仅支持印度账单格式,需要适配多国规则提取供应商、时间、日期、货币四个字段,目前非印度账单的日期、货币提取失败,现有尝试代码如下:
原有尝试代码
时间提取代码
Regex timeRegex = new Regex(@"\b\d{1,2}:\d{2}\b"); Match timeMatch = timeRegex.Match(Result.Text); if (timeMatch.Success) { expenseOcr.processedFields.Time = timeMatch.Value.Trim(); }
日期提取代码(原标注错误的供应商提取代码实际为日期正则)
// extract date Regex dateRegex = new Regex(@"\b(?=\d{2}[ /.-](?:\d{2}|[a-zA-Z]{3,})[ /.-]\d{2,4})(?:\d{1,2}[ /.-])?(?:(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]*)?[ /.-]?\d{1,2}[ /.-]?\d{2,4}\b"); Match dateMatch = dateRegex.Match(Result.Text); if (dateMatch.Success) { expenseOcr.processedFields.Date = dateMatch.Value.Trim(); }
货币提取代码(仅支持INR)
string currencyCode = "en-IN"; // Example value - replace with your actual currency code if (!string.IsNullOrEmpty(currencyCode)) { try { CultureInfo cultureInfo = CultureInfo.GetCultureInfoByIetfLanguageTag(currencyCode); RegionInfo regionInfo = new RegionInfo(cultureInfo.Name); expenseOcr.processedFields.Currency = regionInfo.ISOCurrencySymbol; } catch (CultureNotFoundException) { try { CultureInfo cultureInfo = CultureInfo.CreateSpecificCulture(currencyCode); RegionInfo regionInfo = new RegionInfo(cultureInfo.Name); expenseOcr.processedFields.Currency = regionInfo.ISOCurrencySymbol; } catch (ArgumentException) { // Handle invalid currency code } } }
适配多国格式的优化方案
1. 日期提取(支持多国常见格式)
优化正则,覆盖DD/MM/YYYY、MM/DD/YYYY、DD-MMM-YYYY(含英文/西班牙文月份缩写)、DD.MM.YYYY、DD/MM/AA等格式:
// 支持英文月份(Jan-Dec)、西班牙文月份(Ene-Dic),以及多种分隔符和日期格式 Regex dateRegex = new Regex( @"\b(?:(?:0?[1-9]|[12]\d|3[01])[./-](?:0?[1-9]|1[012])[./-](?:\d{4}|\d{2})|" + @"(?:0?[1-9]|[12]\d|3[01])[./-](?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Ene|Feb|Mar|Abr|May|Jun|Jul|Ago|Sep|Oct|Nov|Dic)[a-z]*[./-](?:\d{4}|\d{2})|" + @"(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec|Ene|Feb|Mar|Abr|May|Jun|Jul|Ago|Sep|Oct|Nov|Dic)[a-z]*[./-](?:0?[1-9]|[12]\d|3[01])[./-](?:\d{4}|\d{2}))\b", RegexOptions.IgnoreCase); Match dateMatch = dateRegex.Match(Result.Text); if (dateMatch.Success) { expenseOcr.processedFields.Date = dateMatch.Value.Trim(); }
说明:正则包含了西班牙文月份缩写(Ene=一月、Abr=四月、Ago=八月、Dic=十二月),同时支持斜杠、点、横杠三种分隔符,兼容两位/四位年份。
2. 时间提取(支持24小时制/12小时制)
原正则仅匹配HH:MM,优化后支持带AM/PM的12小时制格式:
// 匹配24小时制(HH:MM)或12小时制(HH:MM AM/PM) Regex timeRegex = new Regex(@"\b\d{1,2}:\d{2}(?:\s?(?:AM|PM|am|pm))?\b", RegexOptions.IgnoreCase); Match timeMatch = timeRegex.Match(Result.Text); if (timeMatch.Success) { expenseOcr.processedFields.Time = timeMatch.Value.Trim(); }
3. 货币提取(支持多国货币)
去掉硬编码的区域代码,改为从文本中提取货币符号或代码,再映射为ISO标准符号:
// 提取文本中的货币符号或代码(如₹、€、$、INR、EUR、USD) Regex currencyRegex = new Regex(@"\b(?:INR|EUR|USD|GBP|CAD|AUD|₹|€|\$|£)\b", RegexOptions.IgnoreCase); Match currencyMatch = currencyRegex.Match(Result.Text); if (currencyMatch.Success) { string currencySymbol = currencyMatch.Value.ToUpper(); // 映射符号到ISO代码 switch (currencySymbol) { case "₹": expenseOcr.processedFields.Currency = "INR"; break; case "€": expenseOcr.processedFields.Currency = "EUR"; break; case "$": // 可根据账单来源进一步区分USD/CAD/AUD,这里默认USD,或结合其他逻辑 expenseOcr.processedFields.Currency = "USD"; break; case "£": expenseOcr.processedFields.Currency = "GBP"; break; default: expenseOcr.processedFields.Currency = currencySymbol; break; } } else { // fallback:尝试从文本语言推断(可选) // 这里可以根据账单中的其他语言特征调整,比如西班牙文账单默认EUR }
说明:如果需要更精准的货币识别,可以结合账单中的语言关键词(如西班牙文的"Euro")或金额格式(如西班牙用逗号做千位分隔符)进一步判断。
4. 供应商(酒店名称)提取
酒店名称通常在账单顶部,包含"Hotel"、"Resort"、"Inn"、"Hostal"(西班牙文旅馆)等关键词,正则匹配连续的名称文本:
// 匹配包含酒店相关关键词的供应商名称,排除日期、金额等干扰项 Regex vendorRegex = new Regex(@"\b(?:Hotel|Resort|Inn|Hostal|Posada)[\s\w&'-]+", RegexOptions.IgnoreCase); Match vendorMatch = vendorRegex.Match(Result.Text); if (vendorMatch.Success) { expenseOcr.processedFields.Vendor = vendorMatch.Value.Trim(); } else { // fallback:匹配账单开头的连续文本(假设供应商在最顶部) Regex fallbackVendorRegex = new Regex(@"^[\s\w&'-]+", RegexOptions.Multiline); Match fallbackMatch = fallbackVendorRegex.Match(Result.Text); if (fallbackMatch.Success) { expenseOcr.processedFields.Vendor = fallbackMatch.Value.Trim(); } }
说明:针对西班牙账单加入了西班牙语的住宿关键词(Hostal、Posada),如果账单格式特殊,可以根据实际样本调整关键词。
内容的提问来源于stack exchange,提问作者Rahul Gadhave
相关产品推荐
相关产品推荐

