2010-11-09 219 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