如何用C# 10和.NET 10提取首个非百分比结尾的数字
问题描述
我们需要将发票PDF转换为文本,这类文本格式差异极大,包含任意文本、带%标识的增值税税率,以及不跟在%后的金额数字。目标是用正则表达式提取第一个不以百分号(%)结尾的数字,注意数字与%之间可能有空格,也可能没有。
示例文本中预期匹配结果为4.23和5.67,但尝试的正则表达式:
-?[0-9]{1,3}(?:[_,.]?[0-9]{3})*[.,]?[0-9]{0,2}[^%]
返回了错误的3.12。
解决方案
在C# 10/.NET 10中,可利用正向否定预测断言排除后面紧跟%(含可能空格)的数字,同时匹配符合金额格式的数字。
推荐正则表达式
-?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{1,2})?(?!\s*%)
正则规则说明
-?:匹配可选的负号\d{1,3}:匹配1-3位整数部分(?:[.,]\d{3})*:匹配千位分隔符(.或,)加3位数字的重复模式,支持1.234或1,234这类格式(?:[.,]\d{1,2})?:匹配可选的小数部分,支持1-2位小数,小数点或逗号作为分隔符(?!\s*%):正向否定断言,确保数字后没有紧跟任意空格加%
C# 代码示例
using System; using System.Text.RegularExpressions; class InvoiceAmountExtractor { static void Main() { string invoiceText = "示例文本:增值税率 13%,金额 4.23,另一个金额 5.67,税率 9.5 %"; string pattern = @"-?\d{1,3}(?:[.,]\d{3})*(?:[.,]\d{1,2})?(?!\s*%)"; Match firstMatch = Regex.Match(invoiceText, pattern); if (firstMatch.Success) { Console.WriteLine("提取到的第一个金额:" + firstMatch.Value); } } }
原正则失败原因
原正则用[^%]作为结尾,会匹配一个非%的字符,导致错误包含数字后的其他字符,或在数字位于文本末尾时无法匹配。而正向否定断言是零宽断言,不消耗字符,仅检查后续内容,匹配更精准。
内容的提问来源于stack exchange,提问作者Andrus
相关产品推荐
相关产品推荐

