web-dev-qa-db-ja.com

N番目の文字/数字ごとに文字列/数字を分割しますか?

たとえば、数字を偶数の部分に分割する必要があります。
32427237は324 272 37になる必要があります
103092501は103 092 501になる必要があります

次の数字だけができると確信していますが、これらの数字の文字を見逃したくないので、より効率的な方法があると確信しています-数字自体は任意の長さにすることができます1234567890これらの部分に分割したい123 456 789 0

Pythonなどのような他の言語の例を見てきましたが、それらをC#に変換するのに十分に理解していません-文字をループし、3つ目が前を取得してから文字列のセクションを取得するためのインデックスは仕事をするかもしれませんが、私はこれをより良く達成する方法についての提案を受け入れています。

58
RoguePlanetoid

コードの多くの場所でそれを行う必要がある場合は、派手な拡張メソッドを作成できます。

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 望んだ通りに。

109

単純な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();
8
Dirk Vollmar

LINQルール:

var input = "1234567890";
var partSize = 3;

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

更新:

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

1つのveryこれを行う簡単な方法(最も効率的ではありませんが、最も効率的であるよりも桁違いに遅くはありません)。

    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;
    }
5
Binary Worrier

これは半十年遅れですが、:

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()));
5
Tyress

分割方法:

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

編集:私はマーティン・リバーセージのソリューションが好きです:)

編集2:バグを修正しました。

編集3:文字列を結合するコードを追加しました。

3
Fábio Batista

私はこのようなことをしますが、他の方法もあると確信しています。かなりうまく機能するはずです。

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();
}
2
steinar

私はこれが、非常に効率的ではありませんが、そのクールさを引き起こすのが好きです:

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();
2
Sam Saffron

これを試して:

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

文字列全体の長さがパーツサイズで正確に割り切れることがわかっている場合は、次を使用します。

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になりますが、string []またはList <string>値が必要な場合は、末尾に.ToArray()または.ToList()を追加できます。

2
Dave Lampert

他のStackOverflow質問からの回答を使用した素晴らしい実装:

"32427237"
    .AsChunks(3)
    .Select(vc => new String(vc))
    .ToCsv(" ");  // "324 272 37"

"103092501"
    .AsChunks(3)
    .Select(vc => new String(vc))
    .ToCsv(" "); // "103 092 501"

AsChunks(): https://stackoverflow.com/a/22452051/53876

ToCsv(): https://stackoverflow.com/a/45891332/53876

1
crokusek

文字列を分割し、場所ごとに特定の文字数を持つ文字列のリストを返すために、ここに私の関数があります:

public List<string> SplitStringEveryNth(string input, int chunkSize)
    {
        var output = new List<string>();
        var flag = chunkSize;
        var tempString = string.Empty;
        var lenght = input.Length;
        for (var i = 0; i < lenght; i++)
        {
            if (Int32.Equals(flag, 0))
            {
                output.Add(tempString);
                tempString = string.Empty;
                flag = chunkSize;
            }
            else
            {
                tempString += input[i];
                flag--;
            }

            if ((input.Length - 1) == i && flag != 0)
            {
                tempString += input[i];
                output.Add(tempString);
            }
        }
        return output;
    }
0

なぜこのように数字をフォーマットしたいのかわからないので、これはトピックから外れている可能性がありますので、関連がない場合はこの投稿を無視してください...

整数の表示方法は、文化によって異なります。これは、ローカルの独立した方法で行う必要があります。これにより、後で変更をローカライズしやすくなります。

int.ToStringは、さまざまなカルチャのフォーマットに使用できるさまざまなパラメーターを取ります。 "N" パラメーターは、カルチャ固有のグループ化の標準形式を提供します。

steve x文字列のフォーマット も素晴らしいリソースです。

0
simendsjo