2013-05-20 62 views
2

如果我提出一個太明顯的問題,我是一位新手程序員,所以提前很抱歉。替換由數字組成的子字符串

我在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之間),只有我不能得到它的工作...

哦,不幸的是,我的老闆不希望我使用正則表達式,或者我現在已經擁有它。

在此先感謝。

+0

一個字符串可以有多個位置嗎? –

+6

「我的老闆不想讓我使用正則表達式」 - 你的老闆是個傻瓜。請讓他知道StackOverflow的專業人士堅持這一點。 –

+0

子字符串(位置X)可以在大字符串中一次,但它可以改變句子中的位置。 – jonatr

回答

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,這將期望只有一個會被插入到{0}位置string

+0

對不起,如果我不清楚。我得到這樣的句子,我無法控制內容,我必須更換「位置X」。 – jonatr

+1

然後,你的老闆確實是一個白癡:)正則表達式正是爲這些情況(例如,正則表達式用於驗證電子郵件地址的正確性,否則幾乎不可能驗證) –

+0

@Jonathan Perry - 我完全同意:) – paulsm4

0

你在正確的軌道上我在想:

1)你想參數 「位置1 =這家餐廳」, 「位置2 =那個地方」 等中的列表:

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);

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]); 
    } 
0

像其他人說,正則表達式在這裏確實是正確的解決方案,但我們基本上可以做正則表達式在內部做的事情。

注:我還沒有測試過,甚至編譯過這段代碼。這應該匹配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); 
}