【问题标题】:String Replacement parameters字符串替换参数
【发布时间】:2014-01-05 16:53:05
【问题描述】:

(C#)我的代码似乎没问题,但是每当我将 0 作为第二个参数时,它都会显示 “Enemy50”当我想让敌人 57 变成敌人 00 时。我认为第三个 if 语句有问题,但不确定是否修复它。

主要

   string enemy57 = "enemy57";
   Console.WriteLine("The old image name is: " + enemy57);
   Console.WriteLine("New image name: " + BuildingBlock.NextImageName(enemy57, 0));
   Console.ReadLine();


class BuildingBlock
{
    public static string ReplaceOnce(string word, string characters, int position)
    {
        word = word.Remove(position, characters.Length);
        word = word.Insert(position, characters);
        return word;
    }

    public static string GetLastName(string name)
    {
        string result = "";
        int posn = name.LastIndexOf(' ');
        if (posn >= 0) result = name.Substring(posn + 1);
        return result;
    }

    public static string NextImageName(string filename, int newNumber)
    {

        if (newNumber > 9)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
        }
        if (newNumber < 10)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
        }
        if (newNumber == 0)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
        }
        return filename;
    }

【问题讨论】:

  • 这不是你一个小时前问的几乎一样的问题吗? stackoverflow.com/questions/20927305/…
  • @SonerGönül 不,我解决了这个问题,但现在它只是一个小问题
  • 如果 newNumber 为零,您将调用 ReplaceOnce 两次。一次是因为数字小于 10,一次是因为它是零。这是你想要的吗?
  • 如果将 Enemy5 替换为 57 会发生什么?敌人57?如果您的代码不查看现有数字但假定当前字符串已经包含正确的数字位数,那么您的代码本身就有缺陷。

标签: c# string


【解决方案1】:

这里有一个例子,可能会做你想做的事。

它会:

  1. 用新号码替换所有最后的数字
  2. 确保字符串中的新数字与字符串中的原始数字的位数相同(或更多,如果需要)

意思是:

Enemy01, replace with 5, will be Enemy05
Enemy57, replace with 5, will be Enemy05
Enemy1, replace with 57, will be Enemy57

这是一个 LINQPad 程序,演示:

void Main()
{
    NextImageName("Enemy01", 5).Dump();
    NextImageName("Enemy57", 5).Dump();
    NextImageName("Enemy5", 57).Dump();
}

public static string NextImageName(string filename, int newNumber)
{
    var re = new Regex(@"\d+$");
    return re.Replace(filename, match =>
    {
        return newNumber.ToString().PadLeft(match.Length, '0');
    });
}

输出:

Enemy05
Enemy05
Enemy57

正则表达式

\d+$

意思是:

  +- one or more times
  v
\d+$
^^ ^
 | |
 | +-- followed by the end of the string
 |
 digits (0-9)

换句话说:

  • 一位或多位数字 (0-9)
  • 跟在字符串的末尾

【讨论】:

    【解决方案2】:

    您的代码的问题是检查 0 的最后一个 if 语句,但在您检查

    public static string NextImageName(string filename, int newNumber)
    {
        if (newNumber == 0)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
        }
        if (newNumber > 9)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
        }
        if (newNumber < 10)
        {
            return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
        }
        return filename;
    }
    

    或者如果你想作为一个例子,你也可以去掉 ReplaceOnce 方法,像这样:

    public static string NextImageName(string filename, int newNumber)
    {
        if (newNumber == 0)
        {
            return Regex.Replace(filename, @"[\d+]", newNumber.ToString());
        }
        if (newNumber > 9)
        {
            return Regex.Replace(filename, @"(\d+)(?!.*\d)", newNumber.ToString());
        }
        if (newNumber < 10)
        {
            return Regex.Replace(filename, @"(\d)(?!.*\d)", newNumber.ToString());
        }
        return filename;
    }
    

    【讨论】:

      【解决方案3】:

      尝试将您上次调用 ReplaceOnce 替换为

       return ReplaceOnce(filename, newNumber.ToString("D2"), (filename.Length - 2));
      

      问题是因为您传递的整数 0 被转换为长度为 1 个字符的字符串“0”。所以 ReplaceOnce 方法只替换最后一个字符,将 5 保留在适当的位置。

      使用 ToString composite formatting 规则 D2 确保您传递给该方法的任何数字都将被格式化为至少两个字符。

      也就是说,看到你测试 newNumber == 0 你也可以写

       return ReplaceOnce(filename, "00", (filename.Length - 2));
      

      另外,零测试应该在测试

      public static string NextImageName(string filename, int newNumber)
      {
      
          if (newNumber == 0)
          {
              return ReplaceOnce(filename, "00", (filename.Length - 2));
          }
          if (newNumber > 9)
          {
              return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 2));
          }
          if (newNumber < 10)
          {
              return ReplaceOnce(filename, newNumber.ToString(), (filename.Length - 1));
          }
          // Unreachable code ???
          // return filename;
      }
      

      如果您确定 twh 结束字符始终为两位数,并且您想用另外两位数替换当前数字也仅用于一位数 newNumber 您可以编写

      public static string NextImageName(string filename, int newNumber)
      {
          // ToString("D2") forces the 1-9 range to be passed as 0X no need to test 
          return ReplaceOnce(filename, newNumber.ToString("D2"), (filename.Length - 2));
      }
      

      删除所有现在不必要的数字长度测试

      【讨论】:

      • 添加了指向 MSDN 上的复合格式文章的链接。具体见Standard Numeric Format Strings
      • 我该怎么做才能将它们更改为个位数。比如 (Enemy57, 1) 变成 Enemy51,但我希望它变成 Enemy01
      • 对每个调用应用 D2 格式化规则,另外还有一个好处是删除所有 if
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      • 2014-03-21
      相关资源
      最近更新 更多