Splitting a string / number every Nth Character /

2019-01-03 16:42发布

I need to split a number into even parts for example:
32427237 needs to become 324 272 37
103092501 needs to become 103 092 501

I'm sure I could just for-next the numbers, but I'm sure there is a more efficient way as I don't want to miss the characters in these numbers - the numbers themselves can be any length so if the number were 1234567890 I'd want it split into these parts 123 456 789 0

I've seen examples in other languages like Python etc but I don't understand them well enough to convert them to C# - looping though the characters and then at the third getting the previous and then that index to get the section of the string may do the job, but I'm open to suggestions on how to accomplish this better.

13条回答
贼婆χ
2楼-- · 2019-01-03 16:57

If you have to do that in many places in your code you can create a fancy extension method:

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

}

You can then use it like this:

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

The output is 324 272 37 as desired.

查看更多
The star\"
3楼-- · 2019-01-03 16:57

If you know that the whole string's length is exactly divisible by the part size, then use:

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

But if there's a possibility the whole string may have a fractional chunk at the end, you need to little more sophistication:

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

In these examples, parts will be an IEnumerable, but you can add .ToArray() or .ToList() at the end in case you want a string[] or List<string> value.

查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-03 17:01

This might be off topic as I don't know why you wish to format the numbers this way, so please just ignore this post if it's not relevant...

How an integer is shown differs across different cultures. You should do this in a local independent manner so it's easier to localize your changes at a later point.

int.ToString takes different parameters you can use to format for different cultures. The "N" parameter gives you a standard format for culture specific grouping.

steve x string formatting is also a great resource.

查看更多
祖国的老花朵
5楼-- · 2019-01-03 17:05

The splitting method:

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

To join back as a string, delimited by spaces:

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

Edit: I like Martin Liversage solution better :)

Edit 2: Fixed a bug.

Edit 3: Added code to join the string back.

查看更多
祖国的老花朵
6楼-- · 2019-01-03 17:06

I like this cause its cool, albeit not super efficient:

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();
查看更多
等我变得足够好
7楼-- · 2019-01-03 17:08

You could use a simple for loop to insert blanks at every n-th position:

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();
查看更多
登录 后发表回答