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

时间:2013-05-20 05:55:30

标签: c# string replace

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

我在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";

如何以最优雅的方式切出“位置1”以用另一个字符串替换它(这可能会保留餐厅的名称,继续这个例子)??

我想做类似的事情:

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

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

哦,不幸的是我的老板不希望我使用正则表达式,或者我现在已经拥有它。

提前致谢。

4 个答案:

答案 0 :(得分:2)

你也可以使用像:

这样的词典
 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]);
    }

答案 1 :(得分:1)

如何使用格式? 这样的事情可以解决问题:

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,这样只需要一个{{1 }}将被插入string位置。

答案 2 :(得分:0)

你走在正确的轨道上。我在想:

1)你想在列表中参数化“Location 1 = This restaurant”,“Location 2 = That place”等:

http://www.dotnetperls.com/list

http://www.dotnetperls.com/split

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

3)如果可能,事件更好的方法可能是使用C#占位符而不是发明自己的“位置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);

答案 3 :(得分:0)

正如其他人所说,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);
}