【问题标题】:String Get/Update Numeric Value After Specific Character字符串获取/更新特定字符后的数值
【发布时间】:2020-08-11 07:25:17
【问题描述】:

我有一个带有字母数字输入的控制台应用程序。我想从字符的特定位置提取/更新数值。所有角色都是独一无二的。输入中没有相同的字符。例如,在我的程序中,我想从特定的字符 R 中提取/更新数值。 R 是唯一的。它始终为 1,后跟数字。请帮忙。这是我的程序。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp16
{
    class Program
    {
        static void Main(string[] args)
        {
            var input = "JPR5AU75";
            Console.WriteLine(GetNumericValue(input,'R'));
            //Expected output=5
            Console.WriteLine(UpdateNumericValue(input, 'R', 7));
            //Expected output=JPR7AU75

            input = "PR2.9AU75";
            Console.WriteLine(GetNumericValue(input, 'R'));
            //Expected output=2.9
            Console.WriteLine(UpdateNumericValue(input, 'R', 3.5));
            //Expected output=PR3.5AU75

            input = "PKLR555AU75";
            Console.WriteLine(GetNumericValue(input, 'R'));
            //Expected output=555
            Console.WriteLine(UpdateNumericValue(input, 'R', 765));
            //Expected output=PKLR765AU75
            Console.ReadLine();
        }
        static string GetNumericValue(string input, char c)
        {
            var value = "Get numeric value from position of charcter c";
            return value;
        }
        static string UpdateNumericValue(string input, char c, double newVal)
        {
            var value = "Replace numeric value from input where character position starts with c";
            return value;
        }
    }
}

【问题讨论】:

  • 如果我们想将字符串PR2.9AU75中的2.9替换为3.55,应该是PR3.5AU75还是PR3.55AU75
  • 嗨@SowmyadharGourishetty,应该是3.55,因为新值是3.55。
  • 我的逻辑也是这样,我的猜测是正确的。
  • @JobertEnamno - 您问题中的示例是唯一预期的结构吗?即{prefix text}{prefix number}{postfix text}{postfix number}?

标签: c# .net string


【解决方案1】:

这是您的方法的示例代码。运行代码here

在最坏的情况下,时间复杂度将是 O(N),N -> 输入的长度

    static string GetNumericValue(string input, char c)
    {
        int charIndex = input.IndexOf(c);

        StringBuilder sb = new StringBuilder();
        int decimalCount = 0;

        for (int i = charIndex + 1; i < input.Length; i++)
        {
            if (char.IsNumber(input[i]) || input[i] == '.')
            {
                if (input[i] == '.') decimalCount++;
                if (decimalCount > 1) break;

                sb.Append(input[i]);
            }
            else break;
        }
        return sb.ToString();
    }

    static string UpdateNumericValue(string input, char c, double newVal)
    {  
        var numericValue = GetNumericValue(input, c);
        return input.Replace(c + numericValue, c + newVal.ToString());            
    }

【讨论】:

  • 在您的UpdateNumericValue 实现中,您会覆盖每次出现的数值。尝试用char + newValue替换char + oldValue
  • 很好,谢谢
【解决方案2】:

您可以使用正则表达式来提取所需的部分:

$@"{c}([-+]?[0-9]+\.?[0-9]*)" 将匹配字符 c 并在一个组中捕获 0 或 1 个符号,后跟 1 个或多个数字,后跟 0 或 1 个点,然后是 0 个或多个数字

using System.Text.RegularExpressions;

// returns an empty string if no match
static string GetNumericValue(string input, char c)
{
    Regex regex = new Regex($@"{Regex.Escape(c.ToString())}([-+]?\d+\.?\d*)");
    var match = regex.Match(input);
    if (match.Success)
    {
        return match.Groups[1].Value;
    }
    return string.Empty;
}

替换可以使用上面的值,并将第一个匹配的字符串替换为预期的数字:

// returns the unchanged input if no match
static string UpdateNumericValue(string input, char c, double newVal)
{
    var needle = $"{c}{GetNumericValue(input, c)}"; // get the numeric value prepended with the searched character

    if (!string.IsNullOrEmpty(needle))
    {
        var regex = new Regex(Regex.Escape(needle));
        return regex.Replace(input, $"{c}{newVal.ToString()}", 1); // replace first occurence
    }
    return input;
}

var input = "JPR5AU75";

Console.WriteLine(GetNumericValue(input,'R'));
//Expected output=5
Console.WriteLine(UpdateNumericValue(input, 'R', 7));
//Expected output=JPR7AU75

input = "PR2.9AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=2.9
Console.WriteLine(UpdateNumericValue(input, 'R', 3.5));
//Expected output=PR3.5AU75

input = "PKLR555AU75";
Console.WriteLine(GetNumericValue(input, 'R'));
//Expected output=555
Console.WriteLine(UpdateNumericValue(input, 'R', 765));
//Expected output=PKLR765AU75
//Console.ReadLine();

input = "ABCDEF";
Console.WriteLine(GetNumericValue(input, 'C'));
//Expected output=""
Console.WriteLine(UpdateNumericValue(input, 'C', 42));
//Expected output="ABCDEF"

input = "ABCDEF";
Console.WriteLine(GetNumericValue(input, 'F'));
//Expected output=""
Console.WriteLine(UpdateNumericValue(input, 'F', 42));
//Expected output="ABCDEF"

input = "666ABC666ABC555";
Console.WriteLine(GetNumericValue(input, 'C'));
//Expected output="666"
Console.WriteLine(UpdateNumericValue(input, 'C', 42));
//Expected output="666ABC42ABC555"

Try it yourself

【讨论】:

  • 嗨@Cid你能在.NET 4.7.2中转换解决方案吗?它使用的是 .NET 代码,因为我使用的是 .NET 4.7.2,所以出现编译错误。
  • 关于@$"{Regex.Escape(c.ToString())}([-+]?\d+\.?\d*)"$"{c}GetNumericValue(input, c)" 的编译错误?
  • 我编辑了我的答案,并将@$"..." 替换为$@""。第一个版本从 C# 8 开始可用,后一个版本应该在以前的版本中使用
  • 你好@Cid,下面有两行。我只想用 R7 替换 R11.05,但输出仍然是 R11.05。 var输入=“BR11.05AU17.51”; Console.WriteLine(UpdateNumericValue(input, 'R', 7));
  • @JobertEnamno 确实,我有一些错别字,我更新了我的答案
【解决方案3】:

我有一个更容易理解的解决方案:

    static string GetNumericValue(string input, char c)
    {
        int indexStartOfValue = input.IndexOf(c) + 1;       
        
        int valueLength = 0;
        while(Char.IsDigit(input[indexStartOfValue + valueLength]) || input[indexStartOfValue + valueLength] == '.')
            valueLength ++;
        
        return input.Substring(indexStartOfValue, valueLength);
    }
    
    static string UpdateNumericValue(string input, char c, double newVal)
    {
        var numericValue = GetNumericValue(input, c);
        return input.Replace(c + numericValue, c + newVal.ToString());
    }

【讨论】:

  • 不确定输入是否可以像JPR5.55.6AU75,但如果是这种情况,GetNumericValue 的输出会是什么?
  • 不可能用UpdateNumericValue 编写它,因为它不是双精度数,但GetNumericValue 只会返回字符串5.55.6。稍后在代码中将其解析为双精度是行不通的。确实如此。如果需要,您必须在退回之前对 input.Substring(indexStartOfValue, valueLength) 进行消毒。
  • 如果输入为JPR5.55.6AU75,即使当前代码仍然返回5.55.6
猜你喜欢
  • 2013-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-22
  • 2012-12-28
  • 2012-09-16
相关资源
最近更新 更多