2010-11-09 209 views
45

我需要一些分成例如即使部分:
32427237需求,成爲324 272 37
103092501需求,成爲103 092 501每N個字符/數字分割一個字符串/數字?

我敢肯定,我可以只換旁邊的數字,但我相信有一種更有效的方法,因爲我不想錯過這些數字中的字符 - 數字本身可以是任何長度,所以如果數字是1234567890,我想讓它分成這些部分123 456 789 0

我見過像Python等其他語言的例子,但我不明白他們足夠好,將它們轉換爲C# - 循環雖然字符,然後在第三次得到之前和那個索引來獲取字符串的部分可能會做這項工作,但我接受建議如何更好地完成這一點。

+1

是否要將字符串拆分爲三個單獨的字符串o你想插入空格嗎? – 2010-11-09 12:02:25

+2

http://stackoverflow.com/questions/3760152/split-string-to-equal-length-substrings-in-java。所有答案都是在java中,但你可以很容易地將它移植到c#中。 – Emil 2010-11-09 12:04:56

+0

他們會是三個單獨的字符串 – RoguePlanetoid 2010-11-09 12:25:41

回答

90

如果你需要做的是,在很多地方在你的代碼中,你可以創建一個奇特的擴展方法:

static class StringExtensions { 

    public static IEnumerable<String> SplitInParts(this String s, Int32 partLength) { 
    if (s == null) 
     throw new ArgumentNullException("s"); 
    if (partLength <= 0) 
     throw new ArgumentException("Part length has to be positive.", "partLength"); 

    for (var i = 0; i < s.Length; i += partLength) 
     yield return s.Substring(i, Math.Min(partLength, s.Length - i)); 
    } 

} 

然後,您可以使用它像這樣:

var parts = "32427237".SplitInParts(3); 
Console.WriteLine(String.Join(" ", parts)); 

輸出爲324 272 37根據需要。

+1

+1只有使用'n'的解決方案作爲參數。 – st0le 2010-11-09 12:12:46

+2

恕我直言擴展方法在這裏是矯枉過正。所要討論的「數字」是特定類型的事物,例如,一個訂單號。如果你可以限制擴展方法只適用於訂單號,那麼很好。因爲它可以將它應用於恰好存儲在字符串中的任何實體,所以這會破壞封裝。 – 2010-11-09 12:26:49

+0

事實上,我想到了一種方法,可以讓字符串分成任意大小的部分 - 會給這個嘗試一個! – RoguePlanetoid 2010-11-09 12:30:07

3

其中一個非常簡單的方法來做到這一點(不是最有效的,但沒有比最有效的慢幾個數量級)。

public static List<string> GetChunks(string value, int chunkSize) 
    { 
     List<string> triplets = new List<string>(); 
     while (value.Length > chunkSize) 
     { 
      triplets.Add(value.Substring(0, chunkSize)); 
      value = value.Substring(chunkSize); 
     } 
     if (value != "") 
      triplets.Add(value); 
     return triplets; 
    } 

這裏有一個備用

public static List<string> GetChunkss(string value, int chunkSize) 
    { 
     List<string> triplets = new List<string>(); 
     for(int i = 0; i < value.Length; i += chunkSize) 
      if(i + chunkSize > value.Length) 
       triplets.Add(value.Substring(i)); 
      else 
       triplets.Add(value.Substring(i, chunkSize)); 

     return triplets; 
    } 
+0

通用'n'版本會更好。 – st0le 2010-11-09 12:12:13

+0

@ st0le:不適用於變量塊大小的火箭科學:) – 2010-11-09 12:21:34

7

你可以使用一個簡單的for循環的每第n個位置插入空格:

string input = "12345678"; 
StringBuilder sb = new StringBuilder(); 
for (int i = 0; i < input.Length; i++) 
{ 
    if (i % 3 == 0) 
     sb.Append(' '); 
    sb.Append(input[i]); 
} 
string formatted = sb.ToString(); 
+0

這與我原本打算創建的類似,但有興趣查看其他替代方案 – RoguePlanetoid 2010-11-09 12:57:51

0

這可能是題外話,因爲我不知道你爲什麼要這樣數字的格式,所以,請忽略此職位,如果不是有關......在不同的

如何顯示整數不同文化。您應該以本地獨立方式執行此操作,以便稍後本地化您的更改。

int.ToString使用不同的參數,您可以使用不同的參數來格式化不同的文化。 "N"參數爲您提供文化特定分組的標準格式。

steve x string formatting也是一個很好的資源。

+0

他們只是數字我不服從任何類型的正常數字格式,這就是爲什麼我提到字符串/數字,因爲我將要使用它們來處理需要這種特定格式的東西。 – RoguePlanetoid 2010-11-09 12:28:09

3

分裂方法:

public static IEnumerable<string> SplitInGroups(this string original, int size) { 
    var p = 0; 
    var l = original.Length; 
    while (l - p > size) { 
    yield return original.Substring(p, size); 
    p += size; 
    } 
    yield return original.Substring(p); 
} 

要加入回爲一個字符串,用空格分隔:

var joined = String.Join(" ", myNumber.SplitInGroups(3).ToArray()); 

編輯:我喜歡馬丁Liversage更好的解決方案:)

編輯2:修復了一個錯誤。

編輯3:添加了加入字符串的代碼。

2

我會做這樣的事情,雖然我敢肯定還有其他的方法。應該表現不錯。

public static string Format(string number, int batchSize, string separator) 
{  
    StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i <= number.Length/batchSize; i++) 
    { 
    if (i > 0) sb.Append(separator); 
    int currentIndex = i * batchSize; 
    sb.Append(number.Substring(currentIndex, 
       Math.Min(batchSize, number.Length - currentIndex))); 
    } 
    return sb.ToString(); 
} 
1

我喜歡這導致其冷靜,雖然不是超高效:

var n = 3; 
var split = "12345678900" 
      .Select((c, i) => new { letter = c, group = i/n }) 
      .GroupBy(l => l.group, l => l.letter) 
      .Select(g => string.Join("", g)) 
      .ToList(); 
+0

我偏愛Linq自己,但效率是一個要求 - 謝謝你的例子,雖然 – RoguePlanetoid 2010-11-09 12:26:35

5

LINQ規則:

var input = "1234567890"; 
var parts = 3; 

var output = input.ToCharArray() 
    .BufferWithCount(parts) 
    .Select(c => new String(c.ToArray())); 

更新:

string input = "1234567890"; 
double parts = 3; 
int k = 0; 
var output = input 
    .ToLookup(c => Math.Floor(k++/parts)) 
    .Select(e => new String(e.ToArray())); 
+1

System.Linq.EnumerableEx.BufferWithCount是Reactive Extensions for .NET(Rx)的一部分:http://msdn.microsoft.com /en-us/devlabs/ee794896.aspx。你將不得不下載並安裝這個代碼才能運行。 – 2010-11-09 13:51:23

+0

謝謝我以前沒有見過BufferWithCount - 現在我知道爲什麼 - 我已經安裝了Rx,因此可能對其他內容有用。 – RoguePlanetoid 2010-11-10 12:02:55

0

試試這個:

Regex.Split(num.toString(), "(?<=^(.{8})+)"); 
1

如果你知道整個字符串的長度是由零件尺寸整除,則使用:

var whole = "32427237!"; 
var partSize = 3; 
var parts = Enumerable.Range(0, whole.Length/partSize) 
    .Select(i => whole.Substring(i * partSize, partSize)); 

但是,如果有可能整個字符串可能會在年底有一個小數塊,你需要一點技巧:

var whole = "32427237"; 
var partSize = 3; 
var parts = Enumerable.Range(0, (whole.Length + partSize - 1)/partSize) 
    .Select(i => whole.Substring(i * partSize, Math.Min(whole.Length - i * partSize, partSize))); 

在這些例子中,部分將是一個IEnumerable,但你可以在最後的情況下,增加.ToArray()或.ToList()你想有一個字符串[]或列表<字符串>值。

+0

如果您認爲自己正在爲接受的答案增加價值,則應將自己的答案添加到已回答的問題中。看起來不是這樣的。 – 2016-07-03 17:05:16

+0

我不明白。這是這個問題的第10個答案,只有第三個可以在單個語句(使用Linq)中完成,我相信這是最有效的3.我做錯了添加這個不同的,可能更好的答案? – 2016-07-04 20:07:59

2

這是五年的時間晚,但:

int n = 3; 
string originalString = "32427237"; 
string splitString = string.Join(string.Empty,originalString.Select((x, i) => i > 0 && i % n == 0 ? string.Format(" {0}", x) : x.ToString())); 
+2

永遠不會太遲的答案,我想知道,如果有一個LINQ解決方案,這裏是! – RoguePlanetoid 2016-07-12 08:00:19