Вопрос

У меня есть строковое значение, длина которого составляет более 5000 символов, я хочу разделить его на 76 символов длиной с новой строкой в конце каждых 76 символов.как бы мне сделать это на c #?

Это было полезно?

Решение

Если вы записываете данные на Base64, попробуйте написать

Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);

При этом будет вставляться новая строка через каждые 76 символов

Другие советы

С другой стороны, если вы хотите сравнить производительность StringBuilder и string, лучшая статья - это найденный codeproject здесь.

alt text

(Однако это не показывает размер строки)

В двух словах, StringBuilder не работает быстрее до тех пор, пока не будет достигнуто пороговое значение длины строки (или повторного связывания), которое у вас значительно ниже, поэтому придерживайтесь обычных методов конкатенации строк и String.

Попробуй это:

s = Regex.Replace(s, @"(?<=\G.{76})", "\r\n");

Редактировать:По-видимому, это самый медленный метод из всех опубликованных на данный момент.Интересно, как это произойдет, если вы предварительно скомпилируете регулярное выражение:

Regex rx0 = new Regex(@"(?<=\G.{76})");

s = rx0.Replace(s, "\r\n"); // only time this portion

Кроме того, как это соотносится с подходом прямого сопоставления?

Regex rx1 = new Regex(".{76}");

s = rx1.Replace(s, "$0\r\n"); // only time this portion

Мне всегда было интересно, насколько дороги эти неограниченные очки lookbehinds.

Немного уродливее ...но намного быстрее ;) (эта версия заняла 161 тик...У Арика получилось 413)

Я разместил свой тестовый код в своем блоге. http://hackersbasement.com/?p=134 (Я также обнаружил, что StringBuilder работает намного медленнее, чем string.Join)

http://hackersbasement.com/?p=139 <= обновленные результаты

    string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    Stopwatch sw = new Stopwatch();

    sw.Start();
    char[] chopMeArray = chopMe.ToCharArray();
    int totalLength = chopMe.Length;
    int partLength = 12;
    int partCount = (totalLength / partLength) + ((totalLength % partLength == 0) ? 0 : 1);
    int posIndex = 0;
    char[] part = new char[partLength];
    string[] parts = new string[partCount];
    int get = partLength;
    for (int i = 0; i < partCount; i++)
    {
        get = Math.Min(partLength, totalLength - posIndex);
        Array.Copy(chopMeArray, posIndex, part, 0, get);
        parts[i] = new string(part, 0, get);
        posIndex += partLength;
    }

    var output = string.Join("\r\n", parts) + "\r\n";
    sw.Stop();
    Console.WriteLine(sw.ElapsedTicks);
public static string InsertNewLine(string s, int len)
{
    StringBuilder sb = new StringBuilder(s.Length + (int)(s.Length/len) + 1);
    int start = 0;
    for (start=0; start<s.Length-len; start+=len)
    {
        sb.Append(s.Substring(start, len));
        sb.Append(Environment.NewLine);
    }
    sb.Append(s.Substring(start));
    return sb.ToString();
}

где s будет вашей входной строкой и лен желаемая длина строки (76).

string[] FixedSplit(string s, int len)
{
   List<string> output;
   while (s.Length > len)
   {
      output.Add(s.Substring(0, len) + "\n");
      s.Remove(0, len);
   }
   output.Add(s + "\n");
   return output.ToArray();
}
public static IEnumerable<string> SplitString(string s, int length)
{
    var buf = new char[length];
    using (var rdr = new StringReader(s))
    {
        int l;
        l = rdr.ReadBlock(buf, 0, length);
        while (l > 0)
        {
            yield return (new string(buf, 0, l)) + Environment.NewLine;
            l = rdr.ReadBlock(buf, 0, length);
        }
    }
}

Затем собрать их обратно вместе:

string theString = GetLongString();
StringBuilder buf = new StringBuilder(theString.Length + theString.Length/76);
foreach (string s in SplitString(theString, 76) { buf.Append(s); }
string result = buf.ToString();

Или вы могли бы сделать это:

string InsertNewLines(string s, int interval)
{
    char[] buf = new char[s.Length + (int)Math.Ceiling(s.Length / (double)interval)];

    using (var rdr = new StringReader(s))
    {
        for (int i=0; i<buf.Length-interval; i++)
        {
            rdr.ReadBlock(buf, i, interval);
            i+=interval;
            buf[i] = '\n';
        }
        if (i < s.Length)
        {
            rdr.ReadBlock(buf, i, s.Length - i);
            buf[buf.Length - 1] = '\n';
        }
    }
    return new string(buf);
}

Еще один....(первый раз с помощью более медленных последующих запусков, аналогичных более быстрым временам, описанным выше)

private void button1_Click(object sender, EventArgs e)
{
  string chopMe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  Stopwatch sw = new Stopwatch();
  sw.Start();
  string result = string.Join("\r\n", ChopString(chopMe).ToArray());
  sw.Stop();
  MessageBox.Show(result + " " + sw.ToString());
}


public IEnumerable<string> ChopString(string s)
{
  int i = 0;
  while (i < s.Length)
  {
    yield return i + PARTLENGTH <= s.Length ? s.Substring(i,PARTLENGTH) :s.Substring(i) ;
    i += PARTLENGTH;
  }
}

Редактировать:Мне было любопытно посмотреть, насколько быстрой была подстрока...

Длина строки составляет 5000 символов...Я не думаю, что скорость действительно имеет значение, если вы не делаете это тысячи или, может быть, даже миллионы раз, особенно когда в OP даже не упоминалось, что скорость важна.Преждевременная оптимизация?

Я бы, вероятно, использовал рекурсию, поскольку это, на мой взгляд, приведет к простейшему коду.

Это может быть синтаксически некорректно, поскольку я знаю .NET, но не C #.

String ChunkString(String s, Integer chunkLength) {
    if (s.Length <= chunkLength) return s;
    return String.Concat(s.Substring(0, chunkLength), 
                         ChunkString(s.Substring(chunkLength)));
}

в основном для развлечения, вот другое решение, реализованное как метод расширения для string:( используется явно, поэтому будет поддерживать только этот формат для перевода строки);

public static string Split(this string str, int len)
        {
            char org = str.ToCharArray();
            int parts = str.Length / len + (str.Length % len == 0 ? 0 : 1);
            int stepSize = len + newline.Length;
            char[] result = new char[parts * stepSize];
            int resLen = result.Length;

            for (int i =0;i<resLen ;i+stepSize)
            {
                Array.Copy(org,i*len,result,i*stepSize);
                resLen[i++] = '\r';
                resLen[i++] = '\n';
            }
            return new string(result);
        }

В конце концов, это было бы то, что я бы использовал, я думаю

    static string fredou()
    {
        string s = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        int partLength = 12;

        int stringLength = s.Length;
        StringBuilder n = new StringBuilder(stringLength + (int)(stringLength / partLength) + 1);
        int chopSize = 0;
        int pos = 0;

        while (pos < stringLength)
        {
            chopSize = (pos + partLength) < stringLength ? partLength : stringLength - pos;
            n.Append(s , pos, chopSize);
            n.Append("\r\n");
            pos += chopSize;
        }

        return n.ToString();         
    }

посмотрев на строку приложения под отражателем:

    <ComVisible(False)> _
    Public Function AppendLine(ByVal value As String) As StringBuilder
        Me.Append(value)
        Return Me.Append(Environment.NewLine)
    End Function

    Public Shared ReadOnly Property NewLine As String
        Get
            Return ChrW(13) & ChrW(10)
        End Get
    End Property

Для меня, с точки зрения скорости, делаю это вручную > AppendLine

Я разделяю строку на 35

var tempstore ="12345678901234567890123456789012345";
for (int k = 0; k < tempstore.Length; k += 35)
{
   PMSIMTRequest.Append(tempstore.Substring(k, tempstore.Length - k > 35 ? 35 : tempstore.Length - k));
   PMSIMTRequest.Append(System.Environment.NewLine);
}
messagebox.Show(PMSIMTRequest.tostring());

Ответ @M4N очень хорош, но я думаю while statement это легче понять, чем for statement.

public static string InsertNewLine(string source, int len = 76)
{
    var sb = new StringBuilder(source.Length + (int)(source.Length / len) + 1);
    var start = 0;
    while ((start + len) < source.Length)
    {
        sb.Append(source.Substring(start, len));
        sb.Append(Environment.NewLine);
        start += len;
    }
    sb.Append(source.Substring(start));
    return sb.ToString();
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top