替换由数字组成的子字符串

本文关键字:字符串 数字 替换 | 更新日期: 2023-09-27 18:14:26

我是一个新手程序员,如果我问了一个太明显的问题,请提前道歉。

我用c#(WPF)编程。

我有几个字符串是在这个结构中构建的:

string str ="David went to Location 1 to have lunch";
string str2 ="Mike has to walk a mile facing north to reach Location 2";

我怎样才能以最优雅的方式把"Location 1"剪掉,用另一个字符串代替它(这个字符串可能会保留餐厅的名字,继续这个例子)??

我想这样做:

str.replace("Location 1", strRestaurantName);

,但因为它应该是通用的(允许替换所有位置x),它应该是使用str.indexof来获得数字的位置(它可以是1到20之间的数字),只有我不能让它工作…

哦,不幸的是,我的老板不希望我使用正则表达式,否则我现在就有了。

替换由数字组成的子字符串

您也可以使用Dictionary:

 Dictionary<string, string> Restaurants = new Dictionary<string, string>();
    public Form1()
    {
        InitializeComponent();
        Restaurants.Add("Location 1", "ABC Restaurant");
        Restaurants.Add("Location 2", "ABD Restaurant");
        Restaurants.Add("Location 3", "ABE Restaurant");
        Restaurants.Add("Location 4", "ABF Restaurant");
        Restaurants.Add("Location 5", "ABG Restaurant");
    }
    private void button1_Click(object sender, EventArgs e)
    {
      string str ="David went to Location 1 to have lunch";
      string str2 ="Mike has to walk a mile facing north to reach Location 2";
        MessageBox.Show( getRestaurant(str));
        // Result: David went to ABC Restaurant to have lunch
        MessageBox.Show( getRestaurant(str2));
        // Result: Mike has to walk a mile facing north to reach ABD Restaurant
    }
    private String getRestaurant(String msg)
    {
        String restaurantName = "";
        foreach (String loc in Restaurants.Keys)
        {
            if (msg.Contains(loc))
            {
                restaurantName = msg.Replace(loc, Restaurants[loc]);
                break;
            }
        }
        return  String.IsNullOrEmpty(restaurantName) ? msg : restaurantName;
    }

您还可以使用LINQ来缩短getRestaurant方法,如:

    private String getRestaurant(String msg)
    {
        String restaurantName = Restaurants.Keys.FirstOrDefault<String>(v => msg.Contains(v));
        return String.IsNullOrEmpty(restaurantName) ? msg : msg.Replace(restaurantName, Restaurants[restaurantName]);
    }

如何使用格式?像这样的代码应该可以达到这个效果:

string locationString = "some string";
string.Format("David went to {0} to have lunch", locationString);

这将导致以下句子:David went to some string to have lunch

当然,您可以根据需要添加尽可能多的字符串,并且您可以通过一遍又一遍地使用相同的变量数来复制相同的字符串(例如:David went to {0} and {0} to have lunch,这将期望只有一个string将插入{0}位置。

你做对了。我想:

1)你想在列表中参数化"位置1=这家餐厅","位置2=那个地方"等:

http://www.dotnetperls.com/list

http://www.dotnetperls.com/split

2)你的代码将循环遍历每个字符串的每个列表项。或者循环,直到找到匹配。

3)如果可能的话,一个更好的方法可能是使用c#占位符,而不是发明自己的"Location N"语法,例如str.Format("David went to {0} to have lunch", strRestaurantName);str.Format("David went to {0} to have lunch, then Mike has to walk a mile facing north to reach {1}", strRestaurantName, strHikingLocation);

就像其他人说的,Regex确实是正确的解决方案,但我们基本上可以做Regex内部会做的事情。

注意:我没有测试,甚至没有编译这段代码。这应该匹配Location ('d+)

string ReplaceLocation(string input, IList<string> replacements)
{
    string locString = "Location ";
    int matchDigitStart = 0;
    int matchDigitEnd = 0;
    int matchStart = 0;
    do{
        matchStart = input.IndexOf(locString, matchDigitStart);
        if(matchStart == -1)
        {
            throw new ArgumentException("Input string did not contain Location identifier", "input");
        }
        matchDigitStart = matchStart + locString.Length;
        matchDigitEnd = matchDigitStart;
        while(matchDigitEnd < input.Length && Char.IsDigit(input[matchDigitEnd]))
        {
            ++matchDigitEnd;
        }
    } while (matchDigitEnd == matchDigitStart);

    int locationId = int.Parse(input.Substring(matchDigitStart, matchDigitEnd - matchDigitStart));
    if(locationId > replacements.Count || locationId == 0 )
    {
        throw new ArgumentException("Input string specified an out-of-range location identifier", "input");
    }
    return input.Substring(0, matchStart) + replacements[locationId - 1] + input.Substring(matchDigitEnd);
}