You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.02 01:54:52