首页 > 解决方案 > 使用 C# 正则表达式分别提取文本数量的出现

问题描述

我有一些段落多次包含文本金额(例如:保险,每次发生的限额不少于 50万美元和100万美元),以确保不承担所有责任)

我有以下代码负责从文本数量中提取数字。像(一千五百 = 1500)。如果数量仅出现一次,它工作正常,但当文本格式的数量出现不止一次时,它会很困难。返回的数字不正确。

 private static Dictionary<string, long> numberTable = new Dictionary<string, long>
        { {"zero",0},{"one",1},{"two",2},{"three",3},{"four",4},
        {"five",5},{"six",6},{"seven",7},{"eight",8},{"nine",9},
        {"ten",10},{"eleven",11},{"twelve",12},{"thirteen",13},
        {"fourteen",14},{"fifteen",15},{"sixteen",16},
        {"seventeen",17},{"eighteen",18},{"nineteen",19},{"twenty",20},
        {"thirty",30},{"forty",40},{"fifty",50},{"sixty",60},
        {"seventy",70},{"eighty",80},{"ninety",90},{"hundred",100},
        {"thousand",1000},{"million",1000000},{"billion",1000000000},
        {"trillion",1000000000000},{"quadrillion",1000000000000000},
        {"quintillion",1000000000000000000}};


var numbers = Regex.Matches(numberString, @"\w+").Cast<Match>()
                .Select(m => m.Value.ToLowerInvariant())
                .Where(v => numberTable.ContainsKey(v)).Select(v => numberTable[v]);
            long acc = 0, total = 0L;
            foreach (var n in numbers)
            {
                if (n >= 1000)
                {
                    total += (acc * n);
                    acc = 0;
                }
                else if (n >= 100)
                {
                    acc *= n;
                }
                else acc += n;
            }
            string a = Convert.ToString((total + acc) * (numberString.StartsWith("minus", StringComparison.InvariantCultureIgnoreCase) ? -1 : 1));
            return a;

任何人都可以帮助或提出解决问题的建议。

如果我只输入文本“保险限额不少于50美元”,那么输出是正确的,即我们 500,000

但是,如果我输入文本 =“保险,限额不低于每人 50 万美元和100万美元)每次发生的所有责任保险”

然后我得到的答案是 1500000 ,但我需要这个分别像 50,000 和 1000,000

注意:我还想,如果我能把所有的金额都换成美元,然后一一兑换。但我认为这不是一个好的选择,我愿意接受任何形式的讨论。谢谢

标签: c#asp.netregex

解决方案


将您的代码更改为以下代码:

下面我们检查如果数字是数字的延续(即 5 100 1000 美元),我们将它们添加(在上下文中相乘)到存在于 list( sample) 中的相同元素中,否则我们将数据添加到列表的新元素中并且重复这个过程

示例:- 考虑一下 -> 如果我们从 50万美元中删除所有位置, 我们将得到50e万美元 在这里我们可以看到offivehof之间的差值Hundred正好是 1,因此我们可以得出数字相同的结论。

    public static List<long> ToLong(string numberString)
    {
        var numbers = Regex.Matches(numberString, @"\w+").Cast<Match>()
             .Select(m => m.Value.ToLowerInvariant())
             .Where(v => numberTable.ContainsKey(v))
             .Select(v => numberTable[v]);

        long acc = 0, total = 0L;
        List<long> sample = new List<long>();
        int prevIndex = 0, currIndex = 0;
        string currKey = "", prevKey = "";
        int i = 0;
        List<long> revList = numbers.ToList();
        revList.Reverse();
        foreach (var n in numbers)
        {
            numberString = numberString.Replace(" ", "");
            currKey = numberTable.FirstOrDefault(x => x.Value.ToString().ToLower() == n.ToString().ToLower()).Key;
            currIndex = numberString.ToLower().IndexOf(currKey.ToLower());
            bool isDiffNuber = !(prevIndex == 0 || currIndex - (prevIndex + prevKey.Length - 1) == 1);


            if (!isDiffNuber)
            {
                if (n >= 1000)
                {
                    total += (acc * n);
                    acc = 0;
                }
                else if (n >= 100)
                {
                    acc *= n;
                }
                else
                    acc += n;
            }

            if (isDiffNuber || numbers.Last() == n)
            {
                long val = total + acc;
                sample.Add(val);

                i++;
                prevIndex = 0;
                currIndex = 0;
                prevKey = "";
                currKey = "";
                total = 0;
                acc = 1;
            }


            prevIndex = currIndex;
            prevKey = currKey;
        }

        return sample;
    }

注意:- 如果用户添加此解决方案仅适用于上述给定示例,Five Hundred "and" .......则当前示例将无法这样做。

在此处输入图像描述


推荐阅读