C#正则表达式提取发票行项:区分描述小数与金额
发票行项提取的正则表达式优化方案
问题分析
你需要用C#从文本块中提取发票行项的三个字段:Line Item Code、Line Item Description和Line Item Dollar Amount,但当前正则表达式因允许描述部分跨行贪婪匹配,且金额匹配规则不精确,导致描述中的小数(如3.5、2.38)会触发误匹配,将多个行项合并为一个描述。
测试文本
1244 Drayage Charge MEDU2265085 1,875.00 4083 Chassis MEDU2265085 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MEDU2265085 250.00 1248 Truck Waiting & Over Time MEDU2265085 3.5*120 420.00 1244 Drayage Charge MEDU3325790 1,875.00 4083 Chassis MEDU3325790 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MEDU3325790 250.00 1248 Truck Waiting & Over Time MEDU3325790 2.38*120 285.60 1244 Drayage Charge MSCU3870551 1,875.00 4083 Chassis MSCU3870551 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MSCU3870551 250.00 1248 Truck Waiting & Over Time MSCU3870551 3.5*120 420.00
优化后的正则表达式
(?<LINE_ITEM_CODE>\d{4})\s+(?<LINE_ITEM_DESCRIPTION>.+)\r?\n(?<LINE_ITEM_AMOUNT>\d{1,3}(?:,\d{3})*\.\d{2})
规则说明
(?<LINE_ITEM_CODE>\d{4}):匹配4位数字的行项代码,用\d替代[0-9]更简洁。\s+:匹配代码与描述之间的一个或多个空白字符(空格、制表符等)。(?<LINE_ITEM_DESCRIPTION>.+):匹配单行内的所有描述内容(默认模式下.不匹配换行),避免跨行捕获其他行项或金额。\r?\n:兼容Windows(\r\n)和Unix(\n)的换行符,连接描述行与金额行。(?<LINE_ITEM_AMOUNT>\d{1,3}(?:,\d{3})*\.\d{2}):精确匹配带千分位的货币格式,确保只捕获合法金额(如1,875.00、640.00),区分描述中的零散小数(如3.5、2.38)。
C# 使用示例
using System; using System.Text.RegularExpressions; class Program { static void Main() { string invoiceText = @"1244 Drayage Charge MEDU2265085 1,875.00 4083 Chassis MEDU2265085 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MEDU2265085 250.00 1248 Truck Waiting & Over Time MEDU2265085 3.5*120 420.00 1244 Drayage Charge MEDU3325790 1,875.00 4083 Chassis MEDU3325790 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MEDU3325790 250.00 1248 Truck Waiting & Over Time MEDU3325790 2.38*120 285.60 1244 Drayage Charge MSCU3870551 1,875.00 4083 Chassis MSCU3870551 TRIAXLE 4 DAYS 640.00 1268 Pre-Pull MSCU3870551 250.00 1248 Truck Waiting & Over Time MSCU3870551 3.5*120 420.00"; string regexPattern = @"(?<LINE_ITEM_CODE>\d{4})\s+(?<LINE_ITEM_DESCRIPTION>.+)\r?\n(?<LINE_ITEM_AMOUNT>\d{1,3}(?:,\d{3})*\.\d{2})"; foreach (Match match in Regex.Matches(invoiceText, regexPattern)) { string code = match.Groups["LINE_ITEM_CODE"].Value.Trim(); string description = match.Groups["LINE_ITEM_DESCRIPTION"].Value.Trim(); string amount = match.Groups["LINE_ITEM_AMOUNT"].Value.Trim(); Console.WriteLine($"行项代码: {code}"); Console.WriteLine("描述: " + description); Console.WriteLine("金额: " + amount); Console.WriteLine("---"); } } }
额外优化建议
- 如果描述中可能存在换行(当前测试文本中没有),可以启用
RegexOptions.Singleline让.匹配换行,但需调整逻辑确保只捕获到金额前的内容。 - 可对提取的金额进行格式转换(如去除千分位逗号,转为
decimal类型),方便后续计算。
内容的提问来源于stack exchange,提问作者AJ L
相关产品推荐
相关产品推荐

