سؤال

لدي قيمة سلسلة يبلغ طولها أكثر من 5000 حرفًا، وأريد تقسيمها إلى 76 حرفًا مع سطر جديد في نهاية كل 76 حرفًا.كيف أفعل هذا في C#؟

هل كانت مفيدة؟

المحلول

إذا كنت تكتب البيانات باستخدام Base64، حاول كتابة

Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);

وهذا سيتم إدراج سطر جديد كل 76 حرفا

نصائح أخرى

وA الجانبية على هذا، إذا كنت ترغب ب StringBuilder مقابل أداء سلسلة أفضل مقال هو codeproject واحدة العثور على <لأ href = "http://www.codeproject.com/KB/cs/StringBuilder_vs_String.aspx" يختلط = "نوفولو noreferrer "> هنا .

(هذا لا تظهر الحجم سلسلة ولكن)

في وباختصار يمكن القول، ب StringBuilder ليس أسرع حتى يتحقق عتبة مع طول سلسلة (أو contactenation المتكررة)، التي كنت جيدا تحت، لذلك عصا سلسلة سلسلة العادية وطرق سلسلة.

وجرب هذا:

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

أين س سيكون سلسلة الإدخال الخاصة بك و لين طول السطر المطلوب (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 لم أذكر حتى سرعة يجري الهامة. الأمثل من السابق لأوانه؟

وأنا ربما استخدام العودية كما فإنه، في رأيي، أن تؤدي إلى رمز أبسط.

وهذا قد لا يكون صحيحا syntatically، وأنا أعرف .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)));
}

ومعظمها للمتعة من ذلك، وهنا حل مختلف تنفيذها في طريقة تمديد سلسلة: (\ ص \ ن المستخدمة بشكل واضح حتى ستدعم فقط أن شكل السطر الجديد)؛

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

ومن خلال النظر في إضافة AppendLine تحت العاكس:

    <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