2010-10-18 22 views
2

我試圖轉換一個由大寫字母開頭的字符串組成的字符串。我想用空格分隔每個單詞並只保留第一個大寫字母。所有其他字母應該是小寫字母。LINQ將「TheQuickBrownFox」轉換爲「快速棕色狐狸」的方法

例如,「TheQuickBrownFox」將成爲「快速棕色狐狸」。

顯然,我可以使用一個簡單的foreach並通過檢查每個字符來構建一個字符串,但我正在嘗試使用LINQ來完成。

你知道如何使用LINQ優雅地解決這個問題嗎?

謝謝你的幫助。

+7

它應該如何轉換「TheQuickLINQStatement」? – 2010-10-18 13:40:32

+1

你有一個錘子尋找釘子? – jason 2010-10-18 13:59:51

+0

@FredrikMörk幸運的是,這種情況永遠不會出現:) – 2010-10-18 14:03:32

回答

7

您可以使用正則表達式拆分的話(和小LINQ):

public string SplitAsWords(string original) 
{ 
    var matches = Regex.Matches(original, "[A-Z][a-z]*").Cast<Match>(); 
    var str = string.Join(" ", matches.Select(match => match.Value)); 
    str = str[0] + str.Substring(1).ToLower(); 
    return str; 
} 

的利用方法:

[Test] 
public void Example() 
{ 
    string str = SplitAsWords("TheQuickBrownFox"); 
    Assert.That(str, Is.EqualTo("The quick brown fox")); 
} 

使用正則表達式可以替代的實現(無LINQ):

public string SplitAsWords(string original) 
{ 
    var str = Regex.Replace(original, "[a-z][A-Z]", 
     new MatchEvaluator(match => match.Value.ToLower().Insert(1, " "))); 

    return str; 
} 
+0

我接受你的答案,因爲它很好,很乾淨。謝謝! – 2010-10-18 14:13:12

1

這對於「PaulTookTheSAT」或「McDonald's IsNasty」等情況並不理想。

string input = "TheQuickBrownFox"; 
string output = input.Select((c, i) => i == 0 ? c.ToString() : char.IsUpper(c) ? " " + c.ToString().ToLower() : c.ToString()).Aggregate((a,b) => a + b); 

編輯:使用(大部分)查詢表達式語法

string output = (from item in input.Select((c,i) => new { c, i }) 
       let x = item.i == 0 
          ? item.c.ToString() 
          : (char.IsUpper(item.c) ? " " + item.c.ToString().ToLower() : item.c.ToString()) 
       select x).Aggregate((a, b) => a + b); 
1
string s = "TheQuickBrownFox"; 
string transformed = s.Aggregate(new StringBuilder(), (sb, c) => 
    Char.IsUpper(c) && sb.Length > 0 ? sb.AppendFormat(" {0}", Char.ToLower(c)) : sb.Append(c)).ToString(); 
0

隨着System.Text.RegularExpressions.Regexp

System.Text.RegularExpressions.Regex.Split("TheQuickBrownFox","([A-Z][^A-Z]+)").Where(s=>s!=""); 
0

這個怎麼樣?

 string phrase = "TheQuickBrownFox"; 

     var invalidChars = from ch in phrase 
          where char.IsUpper(ch) 
          select ch; 

     foreach (char ch in invalidChars) 
     { 
      int index = phrase.IndexOf(ch); 

      phrase = phrase.Remove(index, 1); 
      phrase = phrase.Insert(index, " " + ch); 
     } 

     Console.WriteLine(phrase); 
     Console.ReadLine(); 
+0

第一次插入foreach循環後索引是否會過時? – 2010-10-18 14:08:45

+0

是的,如果你願意,你也可以只選擇char,然後在foreach循環中調用IndexOf。 – 2010-10-18 14:14:20

0

Linq構建時考慮到了功能風格。使用它的命令方式不會以優雅的代碼結束。所以不要在查詢後轉換,而是在查詢中進行轉換 - 將邏輯放在投影部分(select)中。 (很像安東尼的回答)

var str = (from i in Regex.Split("TheQuickBrownFox", "") 
       select Regex.IsMatch(i, "[A-Z]") ? " " + i : i) 
       .Aggregate((str1, str2) => str1 + str2); 

     Console.WriteLine(str); 
相關問題