StringBuilder Класс

Определение

Предоставляет изменяемую строку символов. Этот класс не наследуется.

public ref class StringBuilder sealed
public ref class StringBuilder sealed : System::Runtime::Serialization::ISerializable
public sealed class StringBuilder
public sealed class StringBuilder : System.Runtime.Serialization.ISerializable
[System.Serializable]
public sealed class StringBuilder
[System.Serializable]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class StringBuilder : System.Runtime.Serialization.ISerializable
type StringBuilder = class
type StringBuilder = class
    interface ISerializable
[<System.Serializable>]
type StringBuilder = class
[<System.Serializable>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type StringBuilder = class
    interface ISerializable
Public NotInheritable Class StringBuilder
Public NotInheritable Class StringBuilder
Implements ISerializable
Наследование
StringBuilder
Атрибуты
Реализации

Примеры

В следующем примере показано, как вызвать множество методов, определенных StringBuilder классом.

using namespace System;
using namespace System::Text;

int main()
{
    // Create a StringBuilder that expects to hold 50 characters.
    // Initialize the StringBuilder with "ABC".
    StringBuilder^ sb = gcnew StringBuilder("ABC", 50);

    // Append three characters (D, E, and F) to the end of the
    // StringBuilder.
    sb->Append(gcnew array<Char>{'D', 'E', 'F'});

    // Append a format string to the end of the StringBuilder.
    sb->AppendFormat("GHI{0}{1}", (Char)'J', (Char)'k');

    // Display the number of characters in the StringBuilder
    // and its string.
    Console::WriteLine("{0} chars: {1}", sb->Length, sb->ToString());

    // Insert a string at the beginning of the StringBuilder.
    sb->Insert(0, "Alphabet: ");

    // Replace all lowercase k's with uppercase K's.
    sb->Replace('k', 'K');

    // Display the number of characters in the StringBuilder
    // and its string.
    Console::WriteLine("{0} chars: {1}", sb->Length, sb->ToString());
}

// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK
using System;
using System.Text;

public sealed class App
{
    static void Main()
    {
        // Create a StringBuilder that expects to hold 50 characters.
        // Initialize the StringBuilder with "ABC".
        StringBuilder sb = new StringBuilder("ABC", 50);

        // Append three characters (D, E, and F) to the end of the StringBuilder.
        sb.Append(new char[] { 'D', 'E', 'F' });

        // Append a format string to the end of the StringBuilder.
        sb.AppendFormat("GHI{0}{1}", 'J', 'k');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());

        // Insert a string at the beginning of the StringBuilder.
        sb.Insert(0, "Alphabet: ");

        // Replace all lowercase k's with uppercase K's.
        sb.Replace('k', 'K');

        // Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString());
    }
}

// This code produces the following output.
//
// 11 chars: ABCDEFGHIJk
// 21 chars: Alphabet: ABCDEFGHIJK
Imports System.Text

Public Module App 
    Public Sub Main() 
        ' Create a StringBuilder that expects to hold 50 characters.
        ' Initialize the StringBuilder with "ABC".
        Dim sb As New StringBuilder("ABC", 50)

        ' Append three characters (D, E, and F) to the end of the StringBuilder.
        sb.Append(New Char() {"D"c, "E"c, "F"c})

        ' Append a format string to the end of the StringBuilder.
        sb.AppendFormat("GHI{0}{1}", "J"c, "k"c)

        ' Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString())

        ' Insert a string at the beginning of the StringBuilder.
        sb.Insert(0, "Alphabet: ")

        ' Replace all lowercase k's with uppercase K's.
        sb.Replace("k", "K")

        ' Display the number of characters in the StringBuilder and its string.
        Console.WriteLine("{0} chars: {1}", sb.Length, sb.ToString())
    End Sub
End Module

' This code produces the following output.
'
' 11 chars: ABCDEFGHIJk
' 21 chars: Alphabet: ABCDEFGHIJK

Комментарии

Этот класс представляет объект, подобный строке, значение которого является изменяемой последовательностью символов.

Содержание

Типы String и StringBuilder

Хотя StringBuilder и String оба представляют последовательности символов, они реализуются по-разному. String является неизменяемым типом. То есть каждая операция, которая, в своюмся, изменяет объект, на String самом деле создает новую строку.

Например, вызов String.Concat метода в следующем примере C# приводит к изменению значения строковой переменной с именем value . Фактически Concat метод возвращает value объект с другим значением и адресом из value объекта, переданного в метод. Обратите внимание, что пример должен быть скомпилирован с /unsafe параметром компилятора.

using System;

public class Example
{
   public unsafe static void Main()
   {
      string value = "This is the first sentence" + ".";
      fixed (char* start = value)
      {
         value = String.Concat(value, "This is the second sentence. ");
         fixed (char* current = value)
         {
            Console.WriteLine(start == current);
         }
      }   
   }
}
// The example displays the following output:
//      False

Для подпрограмм, выполняющих обширную обработку строк (например, приложения, которые изменяют строку несколько раз в цикле), многократное изменение строки может привести к значительному снижению производительности. Альтернативой является использование StringBuilder , которое является изменяемым строковым классом. Изменяемость означает, что после создания экземпляра класса его можно изменить путем добавления, удаления, замены или вставки символов. StringBuilderОбъект поддерживает буфер для размещения расширения в строке. При наличии свободного места новые данные добавляются в буфер. в противном случае выделяется новый буфер большего размера, данные из исходного буфера копируются в новый буфер, а новые данные добавляются в новый буфер.

Важно!

Хотя StringBuilder класс обычно обеспечивает лучшую производительность String , чем класс, не следует автоматически заменять String на, StringBuilder когда требуется управлять строками. Производительность зависит от размера строки, объема памяти, выделяемого для новой строки, системы, в которой выполняется код, и типа операции. Необходимо подготовиться к тестированию кода, чтобы определить StringBuilder , предлагает ли он значительное повышение производительности.

Рассмотрите возможность использования String класса в следующих условиях:

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

  • При выполнении фиксированного числа операций объединения, особенно с строковыми литералами. В этом случае компилятор может объединить операции объединения в одну операцию.

  • Если при построении строки необходимо выполнять широкие операции поиска. В StringBuilder классе отсутствуют методы поиска, такие как IndexOf или StartsWith . Необходимо преобразовать StringBuilder объект в String для этих операций, и это может отрицательно повлиять на производительность при использовании StringBuilder . Дополнительные сведения см. в разделе Поиск текста в объекте StringBuilder .

Рассмотрите возможность использования StringBuilder класса в следующих условиях:

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

  • Если предполагается, что код вносит значительное количество изменений в строку.

Принцип работы StringBuilder

StringBuilder.LengthСвойство указывает количество символов, которое в StringBuilder данный момент содержит объект. При добавлении символов к StringBuilder объекту его длина увеличивается до тех пор, пока не будет равен размеру StringBuilder.Capacity свойства, определяющему количество символов, которое может содержать объект. Если число добавленных символов приводит к StringBuilder превышению размера объекта до его текущей емкости, выделяется новая память, значение Capacity Свойства удваивается, в объект добавляются новые символы StringBuilder , и его Length свойство корректируется. Дополнительная память для StringBuilder объекта выделяется динамически до тех пор, пока не достигнет значения, определенного StringBuilder.MaxCapacity свойством. По достижении максимальной емкости для объекта не может быть выделена память StringBuilder , и при попытке добавить символы или расширить ее после максимальной емкости будет создано ArgumentOutOfRangeException OutOfMemoryException исключение или.

В следующем примере показано, как StringBuilder объект выделяет новую память и увеличивает ее емкость динамически по мере расширения строки, назначенной объекту. Код создает StringBuilder объект, вызывая его конструктор по умолчанию (без параметров). Емкость этого объекта по умолчанию составляет 16 символов, а ее максимальная емкость превышает 2 000 000 000 символов. Добавление строки «это предложение». приводит к новому выделению памяти, так как длина строки (19 символов) превышает емкость объекта по умолчанию StringBuilder . Емкость объекта удваивается до 32 символов, добавляется новая строка, а длина объекта теперь равна 19 символам. Затем код добавляет строку «это дополнительное предложение». к значению StringBuilder объекта 11 раз. Когда операция добавления приводит к StringBuilder превышению емкости объекта, ее существующая емкость удваивается и Append операция завершается с ошибкой.

using System;
using System.Reflection;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb = new StringBuilder();
      ShowSBInfo(sb);
      sb.Append("This is a sentence.");
      ShowSBInfo(sb);
      for (int ctr = 0; ctr <= 10; ctr++) {
         sb.Append("This is an additional sentence.");
         ShowSBInfo(sb);
      }   
   }
   
   private static void ShowSBInfo(StringBuilder sb)
   {
      foreach (var prop in sb.GetType().GetProperties()) {
         if (prop.GetIndexParameters().Length == 0)
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
      }
      Console.WriteLine();
   }
}
// The example displays the following output:
//    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
//    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
//    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
//    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
//    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
//    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360
Imports System.Reflection
Imports System.Text

Module Example
   Public Sub Main()
      Dim sb As New StringBuilder()
      ShowSBInfo(sb)
      sb.Append("This is a sentence.")
      ShowSbInfo(sb)
      For ctr As Integer = 0 To 10
         sb.Append("This is an additional sentence.")
         ShowSbInfo(sb)
      Next   
   End Sub
   
   Public Sub ShowSBInfo(sb As StringBuilder)
      For Each prop In sb.GetType().GetProperties
         If prop.GetIndexParameters().Length = 0 Then
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
         End If   
      Next
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'    Capacity: 16    MaxCapacity: 2,147,483,647    Length: 0
'    Capacity: 32    MaxCapacity: 2,147,483,647    Length: 19
'    Capacity: 64    MaxCapacity: 2,147,483,647    Length: 50
'    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 81
'    Capacity: 128    MaxCapacity: 2,147,483,647    Length: 112
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 143
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 174
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 205
'    Capacity: 256    MaxCapacity: 2,147,483,647    Length: 236
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 267
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 298
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 329
'    Capacity: 512    MaxCapacity: 2,147,483,647    Length: 360

Выделение памяти

Емкость объекта по умолчанию StringBuilder составляет 16 символов, а максимальная емкость по умолчанию — Int32.MaxValue . Эти значения по умолчанию используются при вызове StringBuilder() StringBuilder(String) конструкторов и.

Можно явно определить начальную емкость StringBuilder объекта следующими способами.

  • Путем вызова любого из StringBuilder конструкторов, включающих capacity параметр, при создании объекта.

  • Путем явного присвоения свойству нового значения StringBuilder.Capacity для расширения существующего StringBuilder объекта. Обратите внимание, что свойство создает исключение, если новая емкость меньше, чем существующая емкость, или больше, чем StringBuilder Максимальная емкость объекта.

  • Путем вызова StringBuilder.EnsureCapacity метода с новой емкостью. Новая емкость не должна превышать StringBuilder максимальную емкость объекта. Однако, в отличие от присваивания Capacity свойству, не EnsureCapacity создает исключение, если нужная Новая емкость меньше, чем существующая емкость. в данном случае вызов метода не оказывает никакого влияния.

Если длина строки, назначенной StringBuilder объекту в вызове конструктора, превышает емкость по умолчанию или указанную емкость, Capacity свойству присваивается длина строки, заданной value параметром.

Можно явно определить максимальную емкость StringBuilder объекта, вызвав StringBuilder(Int32, Int32) конструктор. Вы не можете изменить максимальную емкость, назначив MaxCapacity свойству новое значение, так как оно доступно только для чтения.

Как показано в предыдущем разделе, если существующая емкость недостаточна, выделяется дополнительная память, а емкость StringBuilder объекта удваивается до значения, определенного MaxCapacity свойством.

Как правило, емкость по умолчанию и максимальная емкость подходят для большинства приложений. Эти значения можно установить при следующих условиях.

  • Если в конечном итоге размер StringBuilder объекта, вероятно, увеличится слишком большим, обычно он превышает несколько мегабайт. В этом случае может возникнуть некоторый выигрыш в производительности от установки начального Capacity свойства к значительному высокому значению, чтобы исключить необходимость в слишком большом количестве перераспределений памяти.

  • Если код работает в системе с ограниченным объемом памяти. В этом случае может потребоваться установить значение MaxCapacity свойства меньше, чем, Int32.MaxValue Если ваш код обрабатывает большие строки, что может привести к его выполнению в среде с ограниченным объемом памяти.

Создание экземпляра объекта StringBuilder

Экземпляр StringBuilder объекта создается путем вызова одного из шести перегруженных конструкторов классов, которые перечислены в следующей таблице. Три конструктора создают экземпляр StringBuilder объекта, значение которого является пустой строкой, но устанавливает значения и по- Capacity MaxCapacity разному. Остальные три конструктора определяют StringBuilder объект с определенным строковым значением и емкостью. Два из трех конструкторов используют максимальную емкость по умолчанию Int32.MaxValue , а третья позволяет задать максимальную емкость.

Конструктор Строковое значение Capacity Максимальная емкость
StringBuilder() String.Empty 16 Int32.MaxValue
StringBuilder(Int32) String.Empty Определяется capacity параметром Int32.MaxValue
StringBuilder(Int32, Int32) String.Empty Определяется capacity параметром Определяется maxCapacity параметром
StringBuilder(String) Определяется value параметром 16 или value . Length, в зависимости от того, какое значение больше Int32.MaxValue
StringBuilder(String, Int32) Определяется value параметром Определяется capacity параметром или value . Length, в зависимости от того, какое значение больше. Int32.MaxValue
StringBuilder(String, Int32, Int32, Int32) Определяется в value. Substring(startIndex, length) Определяется capacity параметром или value . Length, в зависимости от того, какое значение больше. Int32.MaxValue

В следующем примере используются три из этих перегрузок конструктора для создания экземпляров StringBuilder объектов.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      string value = "An ordinary string";
      int index = value.IndexOf("An ") + 3;
      int capacity = 0xFFFF;
      
      // Instantiate a StringBuilder from a string.
      StringBuilder sb1 = new StringBuilder(value);
      ShowSBInfo(sb1); 
      
      // Instantiate a StringBuilder from string and define a capacity.  
      StringBuilder sb2 = new StringBuilder(value, capacity);   
      ShowSBInfo(sb2); 
      
      // Instantiate a StringBuilder from substring and define a capacity.  
      StringBuilder sb3 = new StringBuilder(value, index, 
                                            value.Length - index, 
                                            capacity );
      ShowSBInfo(sb3); 
   }

   public static void ShowSBInfo(StringBuilder sb)
   {
      Console.WriteLine("\nValue: {0}", sb.ToString());
      foreach (var prop in sb.GetType().GetProperties()) {
         if (prop.GetIndexParameters().Length == 0)
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
      }
      Console.WriteLine();
   }
}
// The example displays the following output:
//    Value: An ordinary string
//    Capacity: 18    MaxCapacity: 2,147,483,647    Length: 18
//    
//    Value: An ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 18
//    
//    Value: ordinary string
//    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 15
Imports System.Text

Module Example
   Public Sub Main()
      Dim value As String = "An ordinary string"
      Dim index As Integer = value.IndexOf("An ") + 3
      Dim capacity As Integer = &hFFFF
      
      ' Instantiate a StringBuilder from a string.
      Dim sb1 As New StringBuilder(value)
      ShowSBInfo(sb1) 
      
      ' Instantiate a StringBuilder from string and define a capacity.  
      Dim sb2 As New StringBuilder(value, capacity)   
      ShowSBInfo(sb2) 
      
      ' Instantiate a StringBuilder from substring and define a capacity.  
      Dim sb3 As New StringBuilder(value, index, 
                                   value.Length - index, 
                                   capacity )
      ShowSBInfo(sb3) 
   End Sub
   
   Public Sub ShowSBInfo(sb As StringBuilder)
      Console.WriteLine()
      Console.WriteLine("Value: {0}", sb.ToString())
      For Each prop In sb.GetType().GetProperties
         If prop.GetIndexParameters().Length = 0 Then
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
         End If   
      Next
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'    Value: An ordinary string
'    Capacity: 18    MaxCapacity: 2,147,483,647    Length: 18
'    
'    Value: An ordinary string
'    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 18
'    
'    Value: ordinary string
'    Capacity: 65,535    MaxCapacity: 2,147,483,647    Length: 15

Вызов методов StringBuilder

Большинство методов, которые изменяют строку в StringBuilder экземпляре, возвращают ссылку на этот же экземпляр. Это позволяет вызывать StringBuilder методы двумя способами:

  • Можно выполнить отдельные вызовы метода и игнорировать возвращаемое значение, как показано в следующем примере.

    using System;
    using System.Text;
    
    public class Example
    {
       public static void Main()
       {
          StringBuilder sb = new StringBuilder();
          sb.Append("This is the beginning of a sentence, ");
          sb.Replace("the beginning of ", "");
          sb.Insert(sb.ToString().IndexOf("a ") + 2, "complete ");
          sb.Replace(",", ".");
          Console.WriteLine(sb.ToString());
       }
    }
    // The example displays the following output:
    //        This is a complete sentence.
    
    Imports System.Text
    
    Module Example
       Public Sub Main()
          Dim sb As New StringBuilder()
          sb.Append("This is the beginning of a sentence, ")
          sb.Replace("the beginning of ", "")
          sb.Insert(sb.ToString().IndexOf("a ") + 2, "complete ")
          sb.Replace(",", ".")
          Console.WriteLine(sb.ToString())
       End Sub
    End Module
    ' The example displays the following output:
    '       This is a complete sentence.
    
  • В одной инструкции можно создать ряд вызовов методов. Это может быть удобно, если вы хотите написать одну инструкцию, которая повязывает последовательные операции. В следующем примере три вызова метода из предыдущего примера консолидируются в одну строку кода.

    using System;
    using System.Text;
    
    public class Example
    {
       public static void Main()
       {
          StringBuilder sb = new StringBuilder("This is the beginning of a sentence, ");
          sb.Replace("the beginning of ", "").Insert(sb.ToString().IndexOf("a ") + 2, 
                                                     "complete ").Replace(",", ".");
          Console.WriteLine(sb.ToString());
       }
    }
    // The example displays the following output:
    //        This is a complete sentence.
    
    Imports System.Text
    
    Module Example
       Public Sub Main()
          Dim sb As New StringBuilder("This is the beginning of a sentence, ")
          sb.Replace("the beginning of ", "").Insert(sb.ToString().IndexOf("a ") + 2, _
                                                     "complete ").Replace(", ", ".")
          Console.WriteLine(sb.ToString())
       End Sub
    End Module
    ' The example displays the following output:
    '       This is a complete sentence.
    

Выполнение операций StringBuilder

Методы класса можно использовать StringBuilder для итерации, добавления, удаления или изменения символов в StringBuilder объекте.

Итерация символов StringBuilder

Доступ к символам в объекте можно получить StringBuilder с помощью StringBuilder.Chars[] Свойства. в C# Chars[] является индексатором; в Visual Basic это свойство класса по умолчанию StringBuilder . Это позволяет задавать или извлекать отдельные символы, используя только индекс, без явной ссылки на Chars[] свойство. Символы в StringBuilder объекте начинаются с индекса 0 (нуля) и продолжают индексироваться Length -1.

В следующем примере показано Chars[] свойство. Он добавляет десять случайных чисел к StringBuilder объекту, а затем выполняет итерацию каждого символа. Если категория символов в Юникоде равна UnicodeCategory.DecimalDigitNumber , она уменьшает число на 1 (или меняет число на 9, если его значение равно 0). В примере отображается содержимое StringBuilder объекта как до, так и после изменения значений отдельных символов.

using System;
using System.Globalization;
using System.Text;

public class Example
{
   public static void Main()
   {
      Random rnd = new Random();
      StringBuilder sb = new StringBuilder();
      
      // Generate 10 random numbers and store them in a StringBuilder.
      for (int ctr = 0; ctr <= 9; ctr++)
         sb.Append(rnd.Next().ToString("N5"));    

      Console.WriteLine("The original string:");
      Console.WriteLine(sb.ToString());
            
      // Decrease each number by one.
      for (int ctr = 0; ctr < sb.Length; ctr++) {
         if (Char.GetUnicodeCategory(sb[ctr]) == UnicodeCategory.DecimalDigitNumber) {
            int number = (int) Char.GetNumericValue(sb[ctr]);
            number--;
            if (number < 0) number = 9;
         
            sb[ctr] = number.ToString()[0];
         }
      }
      Console.WriteLine("\nThe new string:");
      Console.WriteLine(sb.ToString());
   }
}
// The example displays the following output:
//    The original string:
//    1,457,531,530.00000940,522,609.000001,668,113,564.000001,998,992,883.000001,792,660,834.00
//    000101,203,251.000002,051,183,075.000002,066,000,067.000001,643,701,043.000001,702,382,508
//    .00000
//    
//    The new string:
//    0,346,420,429.99999839,411,598.999990,557,002,453.999990,887,881,772.999990,681,559,723.99
//    999090,192,140.999991,940,072,964.999991,955,999,956.999990,532,690,932.999990,691,271,497
//    .99999
Imports System.Globalization
Imports System.Text

Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim sb As New StringBuilder()
      
      ' Generate 10 random numbers and store them in a StringBuilder.
      For ctr As Integer = 0 To 9
         sb.Append(rnd.Next().ToString("N5"))    
      Next
      Console.WriteLine("The original string:")
      Console.WriteLine(sb.ToString())
      Console.WriteLine()
            
      ' Decrease each number by one.
      For ctr As Integer = 0 To sb.Length - 1
         If Char.GetUnicodeCategory(sb(ctr)) = UnicodeCategory.DecimalDigitNumber Then
            Dim number As Integer = CType(Char.GetNumericValue(sb(ctr)), Integer)
            number -= 1
            If number < 0 Then number = 9
         
            sb(ctr) = number.ToString()(0)
         End If
      Next
      Console.WriteLine("The new string:")
      Console.WriteLine(sb.ToString())
   End Sub
End Module
' The example displays the following output:
'    The original string:
'    1,457,531,530.00000940,522,609.000001,668,113,564.000001,998,992,883.000001,792,660,834.00
'    000101,203,251.000002,051,183,075.000002,066,000,067.000001,643,701,043.000001,702,382,508
'    .00000
'    
'    The new string:
'    0,346,420,429.99999839,411,598.999990,557,002,453.999990,887,881,772.999990,681,559,723.99
'    999090,192,140.999991,940,072,964.999991,955,999,956.999990,532,690,932.999990,691,271,497
'    .99999

Индексирование на основе символов со свойством Chars[] может работать очень медленно при следующих условиях:

  • Экземпляр StringBuilder очень большой (например, состоит из нескольких десятков тысяч символов).
  • StringBuilder имеет блоки. То есть повторные вызовы методов, например StringBuilder.Append, автоматически расширили свойство StringBuilder.Capacity объекта и выделили для него новые блоки памяти.

Это значительно влияет на производительность, поскольку при каждом доступе к символу проходится весь связанный список блоков с целью найти правильный буфер для индексации.

Примечание

Даже когда большой объект StringBuilder с блоками использует свойство Chars[] для доступа на основе индекса к одному символу или небольшому количеству символов, это оказывает незначительное влияние на производительность. Как правило, это операция 0(n). Производительность серьезно снижается во время итерации символов в объекте StringBuilder — операция O(n^2).

Если возникают проблемы с производительностью при использовании символьного индексирования с объектами StringBuilder, попробуйте выполнить одно из следующих действий:

  • Преобразуйте экземпляр StringBuilder в String путем вызова метода ToString, а затем получите доступ к символам в строке.

  • Скопируйте содержимое существующего объекта StringBuilder в новый объект StringBuilder с заданным размером. Производительность повышается, так как новый объект StringBuilder не содержит блоков. Пример:

    // sbOriginal is the existing StringBuilder object
    var sbNew = new StringBuilder(sbOriginal.ToString(), sbOriginal.Length);
    
    ' sbOriginal is the existing StringBuilder object
    Dim sbNew = New StringBuilder(sbOriginal.ToString(), sbOriginal.Length)
    
  • Установите для начальной вместимости объекта StringBuilder значение, примерно равное максимальному ожидаемому размеру, путем вызова конструктора StringBuilder(Int32). Имейте в виду, что будет выделен целый блок памяти, даже если StringBuilder редко достигает своего максимального размера.

Добавление текста в объект StringBuilder

StringBuilderКласс включает следующие методы для развертывания содержимого StringBuilder объекта:

  • AppendМетод добавляет строку, подстроку, массив символов, часть массива символов, один символ повторяется несколько раз или строковое представление примитивного типа данных в StringBuilder объект.

  • AppendLineМетод добавляет признак конца строки или строку вместе с признаком конца строки к StringBuilder объекту.

  • AppendFormatМетод добавляет строку составного формата в StringBuilder объект. Строковые представления объектов, входящих в результирующую строку, могут отражать соглашения о форматировании текущего языка и региональных параметров системы или указанного языка и региональных параметров.

  • InsertМетод вставляет строку, подстроку, несколько повторений строки, массив символов, часть массива символов или строковое представление примитивного типа данных в указанной позиции в StringBuilder объекте. Позиция определяется индексом, начинающимся с нуля.

В следующем примере используются Append методы, AppendLine , AppendFormat и Insert для расширения текста StringBuilder объекта.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      // Create a StringBuilder object with no text.
      StringBuilder sb = new StringBuilder();
      // Append some text.
      sb.Append('*', 10).Append(" Adding Text to a StringBuilder Object ").Append('*', 10);
      sb.AppendLine("\n");
      sb.AppendLine("Some code points and their corresponding characters:");
      // Append some formatted text.
      for (int ctr = 50; ctr <= 60; ctr++) {
         sb.AppendFormat("{0,12:X4} {1,12}", ctr, Convert.ToChar(ctr));
         sb.AppendLine();
      }
      // Find the end of the introduction to the column.
      int pos = sb.ToString().IndexOf("characters:") + 11 + 
                Environment.NewLine.Length;
      // Insert a column header.
      sb.Insert(pos, String.Format("{2}{0,12:X4} {1,12}{2}", "Code Unit", 
                                   "Character", "\n"));      

      // Convert the StringBuilder to a string and display it.      
      Console.WriteLine(sb.ToString());      
   }
}
// The example displays the following output:
//    ********** Adding Text to a StringBuilder Object **********
//    
//    Some code points and their corresponding characters:
//    
//       Code Unit    Character
//            0032            2
//            0033            3
//            0034            4
//            0035            5
//            0036            6
//            0037            7
//            0038            8
//            0039            9
//            003A            :
//            003B            ;
//            003C            <
Imports System.Text

Module Example
   Public Sub Main()
      ' Create a StringBuilder object with no text.
      Dim sb As New StringBuilder()
      ' Append some text.
      sb.Append("*"c, 10).Append(" Adding Text to a StringBuilder Object ").Append("*"c, 10)
      sb.AppendLine()
      sb.AppendLine()
      sb.AppendLine("Some code points and their corresponding characters:")
      ' Append some formatted text.
      For ctr = 50 To 60
         sb.AppendFormat("{0,12:X4} {1,12}", ctr, Convert.ToChar(ctr))
         sb.AppendLine()
      Next
      ' Find the end of the introduction to the column.
      Dim pos As Integer = sb.ToString().IndexOf("characters:") + 11 + 
                           Environment.NewLine.Length
      ' Insert a column header.
      sb.Insert(pos, String.Format("{2}{0,12:X4} {1,12}{2}", "Code Unit", 
                                   "Character", vbCrLf))      

      ' Convert the StringBuilder to a string and display it.      
      Console.WriteLine(sb.ToString())      
   End Sub
End Module
' The example displays the following output:
'       ********** Adding Text to a StringBuilder Object **********
'       
'       Some code points and their corresponding characters:
'       
'          Code Unit    Character
'               0032            2
'               0033            3
'               0034            4
'               0035            5
'               0036            6
'               0037            7
'               0038            8
'               0039            9
'               003A            :
'               003B            ;
'               003C            <

Удаление текста из объекта StringBuilder

StringBuilderКласс содержит методы, которые могут уменьшить размер текущего StringBuilder экземпляра. ClearМетод удаляет все символы и устанавливает Length свойство в нуль. RemoveМетод удаляет указанное число символов, начиная с определенной позиции индекса. Кроме того, можно удалять символы из конца StringBuilder объекта, присвоив его Length свойству значение меньше длины текущего экземпляра.

В следующем примере удаляется часть текста из StringBuilder объекта, выводится его результирующая емкость, максимальная емкость и длина свойства длины, а затем вызывается Clear метод для удаления всех символов из StringBuilder объекта.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder sb = new StringBuilder("A StringBuilder object");
      ShowSBInfo(sb);
      // Remove "object" from the text.
      string textToRemove = "object";
      int pos = sb.ToString().IndexOf(textToRemove);
      if (pos >= 0) {
         sb.Remove(pos, textToRemove.Length);
         ShowSBInfo(sb);
      }
      // Clear the StringBuilder contents.
      sb.Clear();
      ShowSBInfo(sb);   
   }

   public static void ShowSBInfo(StringBuilder sb)
   {
      Console.WriteLine("\nValue: {0}", sb.ToString());
      foreach (var prop in sb.GetType().GetProperties()) {
         if (prop.GetIndexParameters().Length == 0)
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb));
      }
      Console.WriteLine();
   }
}
// The example displays the following output:
//    Value: A StringBuilder object
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 22
//    
//    Value: A StringBuilder
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 16
//    
//    Value:
//    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 0
Imports System.Text

Module Example
   Public Sub Main()
      Dim sb As New StringBuilder("A StringBuilder object")
      ShowSBInfo(sb)
      ' Remove "object" from the text.
      Dim textToRemove As String = "object"
      Dim pos As Integer = sb.ToString().IndexOf(textToRemove)
      If pos >= 0
         sb.Remove(pos, textToRemove.Length)
         ShowSBInfo(sb)
      End If
      ' Clear the StringBuilder contents.
      sb.Clear()
      ShowSBInfo(sb)   
   End Sub

   Public Sub ShowSBInfo(sb As StringBuilder)
      Console.WriteLine()
      Console.WriteLine("Value: {0}", sb.ToString())
      For Each prop In sb.GetType().GetProperties
         If prop.GetIndexParameters().Length = 0 Then
            Console.Write("{0}: {1:N0}    ", prop.Name, prop.GetValue(sb))
         End If   
      Next
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'    Value: A StringBuilder object
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 22
'    
'    Value: A StringBuilder
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 16
'    
'    Value:
'    Capacity: 22    MaxCapacity: 2,147,483,647    Length: 0

Изменение текста в объекте StringBuilder

StringBuilder.ReplaceМетод заменяет все вхождения символа или строки во всем StringBuilder объекте или в определенном диапазоне символов. В следующем примере используется Replace метод для замены всех восклицательных знаков (!) на вопросительные знаки (?) в StringBuilder объекте.

using System;
using System.Text;

public class Example
{
   public static void Main()
   {
      StringBuilder MyStringBuilder = new StringBuilder("Hello World!");
      MyStringBuilder.Replace('!', '?');
      Console.WriteLine(MyStringBuilder);
   }
}
// The example displays the following output:
//       Hello World?
Imports System.Text

Module Example
   Public Sub Main()
      Dim MyStringBuilder As New StringBuilder("Hello World!")
      MyStringBuilder.Replace("!"c, "?"c)
      Console.WriteLine(MyStringBuilder)
   End Sub
End Module
' The example displays the following output:
'       Hello World?

Поиск текста в объекте StringBuilder

StringBuilderКласс не включает методы String.Contains , аналогичные String.IndexOf методам, и, String.StartsWith предоставляемым String классом, которые позволяют искать в объекте определенный символ или подстроку. Чтобы определить присутствие или начальную точку символа подстроки, необходимо выполнить поиск String значения, используя либо метод поиска строки, либо метод регулярного выражения. Существует четыре способа реализации таких поисков, как показано в следующей таблице.

Метод Плюсы Минусы
Поиск значений строки перед их добавлением в StringBuilder объект. Полезно для определения того, существует ли подстрока. Не может использоваться, если позиция подстроки индекса важна.
Вызовите ToString и найдите возвращенный String объект. Простая в использовании, если вы назначите весь текст StringBuilder объекту, а затем приступите к его изменению. Громоздкий способ повторного вызова ToString , если необходимо внести изменения до того, как весь текст будет добавлен в StringBuilder объект.

При внесении изменений следует приступать к работе с конца StringBuilder текста объекта.
Используйте Chars[] свойство для последовательного поиска диапазона символов. Полезно, если вы работаете с отдельными символами или небольшой подстрокой. Громоздкий, если количество символов для поиска велико или если логика поиска сложна.

Приводит к очень низкой производительности для объектов, которые увеличились очень крупнее с помощью повторяющихся вызовов методов.
Преобразуйте StringBuilder объект в String объект и выполните изменения String объекта. Полезно, если число изменений невелико. Инвертирует преимущество производительности StringBuilder класса, если число изменений велико.

Рассмотрим эти приемы более подробно.

  • Если целью поиска является определение того, существует ли конкретная подстрока (то есть если вы не заинтересованы в положении подстроки), можно искать строки перед их сохранением в StringBuilder объекте. В следующем примере показана одна возможная реализация. Он определяет StringBuilderFinder класс, конструктор которого передает ссылку на StringBuilder объект и подстроку для поиска в строке. В этом случае в примере предпринимается попытка определить, находится ли записанная температура в градусах Фаренгейта или Цельсия, и добавляет соответствующий вводный текст в начало StringBuilder объекта. Генератор случайных чисел используется для выбора массива, содержащего данные в градусах Цельсия или градусах Фаренгейта.

    using System;
    using System.Text;
    
    public class Example
    {
       public static void Main()
       {
          Random rnd = new Random();
          string[] tempF = { "47.6F", "51.3F", "49.5F", "62.3F" };
          string[] tempC = { "21.2C", "16.1C", "23.5C", "22.9C" };
          string[][] temps = { tempF, tempC }; 
    
          StringBuilder sb = new StringBuilder();
          var f = new StringBuilderFinder(sb, "F");
          var baseDate = new DateTime(2013, 5, 1); 
          String[] temperatures = temps[rnd.Next(2)];
          bool isFahrenheit = false;
          foreach (var temperature in temperatures) {
             if (isFahrenheit)
                sb.AppendFormat("{0:d}: {1}\n", baseDate, temperature);
             else
                isFahrenheit = f.SearchAndAppend(String.Format("{0:d}: {1}\n", 
                                                 baseDate, temperature));
             baseDate = baseDate.AddDays(1);
          }            
          if (isFahrenheit) {
             sb.Insert(0, "Average Daily Temperature in Degrees Fahrenheit");
             sb.Insert(47, "\n\n");
          }
          else {
             sb.Insert(0, "Average Daily Temperature in Degrees Celsius");
             sb.Insert(44, "\n\n");
          }   
          Console.WriteLine(sb.ToString());
       }
    }
    
    public class StringBuilderFinder
    {
       private StringBuilder sb;
       private String text;
       
       public StringBuilderFinder(StringBuilder sb, String textToFind)
       {
          this.sb = sb;
          this.text = textToFind;
       }
       
       public bool SearchAndAppend(String stringToSearch)
       {
          sb.Append(stringToSearch);
          return stringToSearch.Contains(text);
       }
    }
    // The example displays output similar to the following:
    //    Average Daily Temperature in Degrees Celsius
    //    
    //    5/1/2013: 21.2C
    //    5/2/2013: 16.1C
    //    5/3/2013: 23.5C
    //    5/4/2013: 22.9C
    
    Imports System.Text
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          Dim tempF() As String = { "47.6F", "51.3F", "49.5F", "62.3F" }
          Dim tempC() As String = { "21.2C", "16.1C", "23.5C", "22.9C" }
          Dim temps()() As String = { tempF, tempC } 
    
          Dim sb As StringBuilder = New StringBuilder()
          Dim f As New StringBuilderFinder(sb, "F")
          Dim baseDate As New DateTime(2013, 5, 1) 
          Dim temperatures() As String = temps(rnd.Next(2))
          Dim isFahrenheit As Boolean = False
          For Each temperature In temperatures
             If isFahrenheit Then
                sb.AppendFormat("{0:d}: {1}{2}", baseDate, temperature, vbCrLf)
             Else
                isFahrenheit = f.SearchAndAppend(String.Format("{0:d}: {1}{2}", 
                                                 baseDate, temperature, vbCrLf))
             End If
             baseDate = baseDate.AddDays(1)
          Next            
          If isFahrenheit Then
             sb.Insert(0, "Average Daily Temperature in Degrees Fahrenheit")
             sb.Insert(47, vbCrLf + vbCrLf)
          Else
             sb.Insert(0, "Average Daily Temperature in Degrees Celsius")
             sb.Insert(44, vbCrLf + vbCrLf)
          End If   
          Console.WriteLine(sb.ToString())
       End Sub
    End Module
    
    Public Class StringBuilderFinder
       Private sb As StringBuilder
       Private text As String
       
       Public Sub New(sb As StringBuilder, textToFind As String)
          Me.sb = sb
          text = textToFind
       End Sub
       
       Public Function SearchAndAppend(stringToSearch As String) As Boolean
          sb.Append(stringToSearch)
          Return stringToSearch.Contains(text)
       End Function
    End Class
    ' The example displays output similar to the following:
    '    Average Daily Temperature in Degrees Celsius
    '    
    '    5/1/2013: 21.2C
    '    5/2/2013: 16.1C
    '    5/3/2013: 23.5C
    '    5/4/2013: 22.9C
    
  • Вызовите StringBuilder.ToString метод, чтобы преобразовать StringBuilder объект в String объект. Можно выполнять поиск в строке с помощью таких методов String.LastIndexOf , как или String.StartsWith , или использовать регулярные выражения и Regex класс для поиска шаблонов. Поскольку оба StringBuilder String объекта и используют кодировку UTF-16 для хранения символов, позиции индекса, подстроки и совпадения регулярных выражений одинаковы в обоих объектах. Это позволяет использовать StringBuilder методы для внесения изменений в той же позиции, в которой этот текст находится в String объекте.

    Примечание

    При применении этого подхода следует работать с конца StringBuilder объекта до начала, чтобы не нужно было повторно преобразовывать StringBuilder объект в строку.

    Этот подход показан в приведенном ниже примере. Он сохраняет четыре вхождения каждой буквы английского алфавита в StringBuilder объекте. Затем он преобразует текст в String объект и использует регулярное выражение для обнаружения начальной позиции каждой последовательности из четырех символов. Наконец, он добавляет символ подчеркивания перед каждой последовательностью из четырех символов, за исключением первой последовательности, и преобразует первый символ последовательности в верхний регистр.

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          // Create a StringBuilder object with 4 successive occurrences 
          // of each character in the English alphabet. 
          StringBuilder sb = new StringBuilder();
          for (ushort ctr = (ushort)'a'; ctr <= (ushort) 'z'; ctr++)
             sb.Append(Convert.ToChar(ctr), 4);
          
          // Create a parallel string object.
          String sbString = sb.ToString();
          // Determine where each new character sequence begins.
          String pattern = @"(\w)\1+";
          MatchCollection matches = Regex.Matches(sbString, pattern);
    
          // Uppercase the first occurrence of the sequence, and separate it
          // from the previous sequence by an underscore character.
          for (int ctr = matches.Count - 1; ctr >= 0; ctr--) { 
             Match m = matches[ctr];
             sb[m.Index] = Char.ToUpper(sb[m.Index]);
             if (m.Index > 0) sb.Insert(m.Index, "_");
          }
          // Display the resulting string.
          sbString = sb.ToString();
          int line = 0;
          do {
             int nChars = line * 80 + 79 <= sbString.Length ? 
                                 80 : sbString.Length - line * 80;
             Console.WriteLine(sbString.Substring(line * 80, nChars));
             line++;
          } while (line * 80 < sbString.Length);
       }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          ' Create a StringBuilder object with 4 successive occurrences 
          ' of each character in the English alphabet. 
          Dim sb As New StringBuilder()
          For ctr As UShort = AscW("a") To Ascw("z")
             sb.Append(ChrW(ctr), 4)
          Next    
          ' Create a parallel string object.
          Dim sbString As String = sb.ToString()
          ' Determine where each new character sequence begins.
          Dim pattern As String = "(\w)\1+"
          Dim matches As MatchCollection = Regex.Matches(sbString, pattern)
    
          ' Uppercase the first occurrence of the sequence, and separate it
          ' from the previous sequence by an underscore character.
          For ctr As Integer = matches.Count - 1 To 0 Step -1 
             Dim m As Match = matches(ctr)
             sb.Chars(m.Index) = Char.ToUpper(sb.Chars(m.index))
             If m.Index > 0 Then sb.Insert(m.Index, "_")
          Next
          ' Display the resulting string.
          sbString = sb.ToString()
          Dim line As Integer = 0
          Do
             Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length, 
                                        80, sbString.Length - line * 80)
             Console.WriteLine(sbString.Substring(line * 80, nChars))
             line += 1
          Loop While line * 80 < sbString.Length
       End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
  • Используйте StringBuilder.Chars[] свойство для последовательного поиска диапазона символов в StringBuilder объекте. Этот подход может оказаться нецелесообразным, если количество символов для поиска является большим или логика поиска особенно сложна. Сведения о влиянии посимвольного доступа на индексы для очень больших фрагментированных StringBuilder объектов см. в документации по StringBuilder.Chars[] свойству.

    Следующий пример аналогичен функции предыдущего примера, но отличается в реализации. Он использует Chars[] свойство для обнаружения изменения значения символа, вставляет символ подчеркивания в эту точку и преобразует первый символ в новой последовательности в верхний регистр.

    using System;
    using System.Text;
    
    public class Example
    {
       public static void Main()
       {
          // Create a StringBuilder object with 4 successive occurrences 
          // of each character in the English alphabet. 
          StringBuilder sb = new StringBuilder();
          for (ushort ctr = (ushort) 'a'; ctr <= (ushort) 'z'; ctr++)
             sb.Append(Convert.ToChar(ctr), 4);
    
          // Iterate the text to determine when a new character sequence occurs.
          int position = 0;
          Char current = '\u0000';
          do {
             if (sb[position] != current) {
                current = sb[position];
                sb[position] = Char.ToUpper(sb[position]);
                if (position > 0) 
                   sb.Insert(position, "_");
                position += 2;
             }
             else {
                position++;
             }      
          } while (position <= sb.Length - 1);
          // Display the resulting string.
          String sbString = sb.ToString();
          int line = 0;
          do {
             int nChars = line * 80 + 79 <= sbString.Length ? 
                                 80 : sbString.Length - line * 80;
             Console.WriteLine(sbString.Substring(line * 80, nChars));
             line++;
          } while (line * 80 < sbString.Length);
       }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    
    Module Example
       Public Sub Main()
          ' Create a StringBuilder object with 4 successive occurrences 
          ' of each character in the English alphabet. 
          Dim sb As New StringBuilder()
          For ctr As UShort = AscW("a") To Ascw("z")
             sb.Append(ChrW(ctr), 4)
          Next    
          ' Iterate the text to determine when a new character sequence occurs.
          Dim position As Integer = 0
          Dim current As Char = ChrW(0)
          Do
             If sb(position) <> current Then
                current = sb(position)
                sb(position) = Char.ToUpper(sb(position))
                If position > 0 Then sb.Insert(position, "_")
                position += 2
             Else
                position += 1
             End If      
          Loop While position <= sb.Length - 1
          ' Display the resulting string.
          Dim sbString As String = sb.ToString()
          Dim line As Integer = 0
          Do
             Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length, 
                                        80, sbString.Length - line * 80)
             Console.WriteLine(sbString.Substring(line * 80, nChars))
             line += 1
          Loop While line * 80 < sbString.Length
       End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
  • Сохраните весь неизмененный текст в StringBuilder объекте, вызовите StringBuilder.ToString метод, чтобы преобразовать StringBuilder объект в String объект и выполнить изменения String объекта. Этот подход можно использовать, если имеется всего несколько изменений. в противном случае стоимость работы с неизменяемыми строками может отрицательно отменять преимущества производительности при использовании StringBuilder объекта.

    Следующий пример аналогичен функциям предыдущих двух примеров, но отличается в реализации. Он создает StringBuilder объект, преобразует его в String объект, а затем использует регулярное выражение для выполнения всех оставшихся изменений в строке. Regex.Replace(String, String, MatchEvaluator)Метод использует лямбда-выражение для замены каждого соответствия.

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    
    public class Example
    {
       public static void Main()
       {
          // Create a StringBuilder object with 4 successive occurrences 
          // of each character in the English alphabet. 
          StringBuilder sb = new StringBuilder();
          for (ushort ctr = (ushort)'a'; ctr <= (ushort) 'z'; ctr++)
             sb.Append(Convert.ToChar(ctr), 4);
         
          // Convert it to a string.
          String sbString = sb.ToString();
    
          // Use a regex to uppercase the first occurrence of the sequence, 
          // and separate it from the previous sequence by an underscore.
          string pattern = @"(\w)(\1+)";
          sbString = Regex.Replace(sbString, pattern, 
                                   m => (m.Index > 0 ? "_" : "") + 
                                   m.Groups[1].Value.ToUpper() + 
                                   m.Groups[2].Value);
    
          // Display the resulting string.
          int line = 0;
          do {
             int nChars = line * 80 + 79 <= sbString.Length ? 
                                 80 : sbString.Length - line * 80;
             Console.WriteLine(sbString.Substring(line * 80, nChars));
             line++;
          } while (line * 80 < sbString.Length);
       }
    }
    // The example displays the following output:
    //    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    //    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    
    Imports System.Text
    Imports System.Text.RegularExpressions
    
    Module Example
       Public Sub Main()
          ' Create a StringBuilder object with 4 successive occurrences 
          ' of each character in the English alphabet. 
          Dim sb As New StringBuilder()
          For ctr As UShort = AscW("a") To Ascw("z")
             sb.Append(ChrW(ctr), 4)
          Next    
          ' Convert it to a string.
          Dim sbString As String = sb.ToString()
    
          ' Use a regex to uppercase the first occurrence of the sequence, 
          ' and separate it from the previous sequence by an underscore.
          Dim pattern As String = "(\w)(\1+)"
          sbString = Regex.Replace(sbString, pattern, 
                                   Function(m) If(m.Index > 0,"_","") + 
                                               m.Groups(1).Value.ToUpper + 
                                               m.Groups(2).Value)
    
          ' Display the resulting string.
          Dim line As Integer = 0
          Do
             Dim nChars As Integer = If(line * 80 + 79 <= sbString.Length, 
                                        80, sbString.Length - line * 80)
             Console.WriteLine(sbString.Substring(line * 80, nChars))
             line += 1
          Loop While line * 80 < sbString.Length
       End Sub
    End Module
    ' The example displays the following output:
    '    Aaaa_Bbbb_Cccc_Dddd_Eeee_Ffff_Gggg_Hhhh_Iiii_Jjjj_Kkkk_Llll_Mmmm_Nnnn_Oooo_Pppp_
    '    Qqqq_Rrrr_Ssss_Tttt_Uuuu_Vvvv_Wwww_Xxxx_Yyyy_Zzzz
    

Преобразование объекта StringBuilder в строку

Необходимо преобразовать объект StringBuilder в String, прежде чем передавать представленную объектом StringBuilder строку методу, который содержит параметр String, или вывести ее в пользовательском интерфейсе. Это преобразование выполняется путем вызова StringBuilder.ToString метода. Иллюстрации см. в предыдущем примере, который вызывает ToString метод для преобразования StringBuilder объекта в строку, чтобы его можно было передать в метод регулярного выражения.

Примечания для тех, кто вызывает этот метод

в .net Core и в платформа .NET Framework 4,0 и более поздних версиях при создании экземпляра StringBuilder объекта путем вызова StringBuilder(Int32, Int32) конструктора длина и емкость StringBuilder экземпляра могут увеличиваться за пределами значения его MaxCapacity свойства. Это может произойти в частности при вызове Append(String) AppendFormat(String, Object) методов и для добавления небольших строк.

Конструкторы

StringBuilder()

Инициализирует новый экземпляр класса StringBuilder.

StringBuilder(Int32)

Инициализирует новый экземпляр класса StringBuilder, используя указанную емкость.

StringBuilder(Int32, Int32)

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

StringBuilder(String)

Инициализирует новый экземпляр класса StringBuilder, используя указанную строку.

StringBuilder(String, Int32)

Инициализирует новый экземпляр класса StringBuilder, используя указанную строку и емкость.

StringBuilder(String, Int32, Int32, Int32)

Инициализирует новый экземпляр класса StringBuilder из указанной подстроки и емкости.

Свойства

Capacity

Возвращает или задает максимальное число знаков, которое может содержаться в памяти, назначенной текущим экземпляром.

Chars[Int32]

Возвращает или задает символ на указанной позиции в данном экземпляре.

Length

Возвращает или задает длину текущего объекта StringBuilder.

MaxCapacity

Возвращает максимальную емкость данного экземпляра.

Методы

Append(Boolean)

Добавляет строковое представление указанного логического значения к данному экземпляру.

Append(Byte)

Добавляет строковое представление указанного 8-разрядного целого числа без знака к данному экземпляру.

Append(Char)

Добавляет строковое представление указанного объекта Char в данный экземпляр.

Append(Char*, Int32)

Добавляет к данному экземпляру массив символов Юникода начиная с указанного адреса.

Append(Char, Int32)

Добавляет указанное число копий строкового представления символа Юникода к данному экземпляру.

Append(Char[])

Добавляет строковое представление символа Юникода в указанном массиве к данному экземпляру.

Append(Char[], Int32, Int32)

Добавляет строковое представление указанного дочернего массива символов Юникода к данному экземпляру.

Append(Decimal)

Добавляет строковое представление указанного десятичного числа к данному экземпляру.

Append(Double)

Добавляет строковое представление указанного числа с плавающей запятой с удвоенной точностью к данному экземпляру.

Append(IFormatProvider, StringBuilder+AppendInterpolatedStringHandler)

Добавляет указанную строку с интерполяцией в этот экземпляр, используя указанный формат.

Append(Int16)

Добавляет строковое представление указанного 16-разрядного целого числа со знаком к данному экземпляру.

Append(Int32)

Добавляет строковое представление указанного 32-разрядного целого числа со знаком к данному экземпляру.

Append(Int64)

Добавляет строковое представление указанного 64-разрядного целого числа со знаком к данному экземпляру.

Append(Object)

Добавляет строковое представление указанного объекта к данному экземпляру.

Append(ReadOnlyMemory<Char>)

Добавляет строковое представление указанной области памяти символов только для чтения к данному экземпляру.

Append(ReadOnlySpan<Char>)

Добавляет строковое представление указанного диапазона символов только для чтения к данному экземпляру.

Append(SByte)

Добавляет строковое представление указанного 8-разрядного целого числа со знаком к данному экземпляру.

Append(Single)

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

Append(String)

Добавляет копию указанной строки к данному экземпляру.

Append(String, Int32, Int32)

Добавляет копию указанной подстроки к данному экземпляру.

Append(StringBuilder)

Добавляет строковое представление указанного построителя строки к данному экземпляру.

Append(StringBuilder, Int32, Int32)

Добавляет копию подстроки в пределах указанного построителя строки к данному экземпляру.

Append(StringBuilder+AppendInterpolatedStringHandler)

Добавляет указанную строку с интерполяцией в этот экземпляр.

Append(UInt16)

Добавляет строковое представление указанного 16-разрядного целого числа без знака к данному экземпляру.

Append(UInt32)

Добавляет строковое представление указанного 32-разрядного целого числа без знака к данному экземпляру.

Append(UInt64)

Добавляет строковое представление указанного 64-разрядного целого числа без знака к данному экземпляру.

AppendFormat(IFormatProvider, String, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением одного аргумента с использованием указанного поставщика формата.

AppendFormat(IFormatProvider, String, Object, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением любого из двух аргументов с помощью указанного поставщика формата.

AppendFormat(IFormatProvider, String, Object, Object, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением любого из трех аргументов с помощью указанного поставщика формата.

AppendFormat(IFormatProvider, String, Object[])

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением соответствующего аргумента в массиве параметров с помощью указанного поставщика формата.

AppendFormat(String, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением одного аргумента.

AppendFormat(String, Object, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением любого из двух аргументов.

AppendFormat(String, Object, Object, Object)

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением любого из трех аргументов.

AppendFormat(String, Object[])

Добавляет к данному экземпляру строку, возвращаемую в результате обработки строки составного формата, содержащей ноль или более элементов формата. Каждый элемент формата заменяется строковым представлением соответствующего аргумента в массиве параметров.

AppendJoin(Char, Object[])

Сцепляет строковые представления элементов из указанного массива объектов, помещая между ними заданный символьный разделитель, а затем добавляет результат к текущему экземпляру построителя строк.

AppendJoin(Char, String[])

Сцепляет строки из указанного массива, помещая между ними заданный символьный разделитель, а затем добавляет результат к текущему экземпляру построителя строк.

AppendJoin(String, Object[])

Сцепляет строковые представления элементов из указанного массива объектов, помещая между ними заданный разделитель, а затем добавляет результат к текущему экземпляру построителя строк.

AppendJoin(String, String[])

Сцепляет строки из указанного массива, помещая между ними заданный разделитель, а затем добавляет результат к текущему экземпляру построителя строк.

AppendJoin<T>(Char, IEnumerable<T>)

Сцепляет и добавляет элементы коллекции, помещая между ними заданный символьный разделитель.

AppendJoin<T>(String, IEnumerable<T>)

Сцепляет и добавляет элементы коллекции, помещая между ними заданный разделитель.

AppendLine()

Добавляет знак завершения строки по умолчанию в конец текущего объекта StringBuilder.

AppendLine(IFormatProvider, StringBuilder+AppendInterpolatedStringHandler)

Добавляет указанную интерполяцию строки с использованием указанного формата, за которым следует признак конца строки по умолчанию, в конец текущего объекта StringBuilder.

AppendLine(String)

Добавляет копию указанной строки и знак завершения строки по умолчанию в конец текущего объекта StringBuilder.

AppendLine(StringBuilder+AppendInterpolatedStringHandler)

Добавляет указанную интерполяцию строки, за которой следует признак конца строки по умолчанию, в конец текущего объекта StringBuilder.

Clear()

Удаляет все символы из текущего экземпляра StringBuilder.

CopyTo(Int32, Char[], Int32, Int32)

Копирует символы из указанного сегмента этого экземпляра в указанный массив Char.

CopyTo(Int32, Span<Char>, Int32)

Копирует символы из указанного сегмента этого экземпляра в конечный диапазон Char.

EnsureCapacity(Int32)

Гарантирует, что емкость данного экземпляра StringBuilder не меньше указанного значения.

Equals(Object)

Определяет, равен ли указанный объект текущему объекту.

(Унаследовано от Object)
Equals(ReadOnlySpan<Char>)

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

Equals(StringBuilder)

Возвращает значение, показывающее, равен ли данный экземпляр заданному объекту.

GetChunks()

Возвращает объект, который можно использовать для прохода по фрагментам символов, представленных в ReadOnlyMemory<Char>, созданном из данного экземпляра StringBuilder.

GetHashCode()

Служит хэш-функцией по умолчанию.

(Унаследовано от Object)
GetType()

Возвращает объект Type для текущего экземпляра.

(Унаследовано от Object)
Insert(Int32, Boolean)

Вставляет строковое представление логического значения в данный экземпляр на указанную позицию символа.

Insert(Int32, Byte)

Вставляет строковое представление указанного 8-разрядного целого числа без знака в данный экземпляр на указанную позицию символа.

Insert(Int32, Char)

Вставляет строковое представление указанного символа Юникода в данный экземпляр на указанную позицию символа.

Insert(Int32, Char[])

Вставляет строковое представление указанного массива символов Юникода в данный экземпляр на указанную позицию символа.

Insert(Int32, Char[], Int32, Int32)

Вставляет строковое представление указанного подмассива символов Юникода в данный экземпляр на указанную позицию символа.

Insert(Int32, Decimal)

Вставляет строковое представление десятичного числа в данный экземпляр на указанную позицию символа.

Insert(Int32, Double)

Вставляет строковое представление числа с плавающей запятой с удвоенной точностью в данный экземпляр на указанную позицию символа.

Insert(Int32, Int16)

Вставляет строковое представление указанного 16-разрядного знакового целого числа в данный экземпляр на указанную позицию символа.

Insert(Int32, Int32)

Вставляет строковое представление указанного 32-разрядного знакового целого числа в данный экземпляр на указанную позицию символа.

Insert(Int32, Int64)

Вставляет строковое представление 64-разрядного знакового целого числа в данный экземпляр на указанную позицию символа.

Insert(Int32, Object)

Вставляет строковое представление объекта в данный экземпляр на указанную позицию символа.

Insert(Int32, ReadOnlySpan<Char>)

Вставляет последовательность символов в этот экземпляр в заданной позиции символа.

Insert(Int32, SByte)

Вставляет строковое представление указанного 8-разрядного знакового целого числа в данный экземпляр на указанную позицию символа.

Insert(Int32, Single)

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

Insert(Int32, String)

Вставляет строку в данный экземпляр на указанную позицию символа.

Insert(Int32, String, Int32)

Вставляет одну или более копий указанной строки в данный экземпляр на указанную позицию символа.

Insert(Int32, UInt16)

Вставляет строковое представление 16-разрядного целого числа без знака в данный экземпляр на указанную позицию символа.

Insert(Int32, UInt32)

Вставляет строковое представление 32-разрядного целого числа без знака в данный экземпляр на указанную позицию символа.

Insert(Int32, UInt64)

Вставляет строковое представление 64-разрядного целого числа без знака в данный экземпляр на указанную позицию символа.

MemberwiseClone()

Создает неполную копию текущего объекта Object.

(Унаследовано от Object)
Remove(Int32, Int32)

Удаляет указанный диапазон символов из данного экземпляра.

Replace(Char, Char)

Замещает все вхождения указанного символа в данном экземпляре на другой указанный знак.

Replace(Char, Char, Int32, Int32)

Замещает все вхождения указанного символа в подстроке данного экземпляра на другой указанный символ.

Replace(String, String)

Замещает все вхождения указанной строки в данном экземпляре на другую указанную строку.

Replace(String, String, Int32, Int32)

Замещает все вхождения указанной строки в подстроке данного экземпляра на другую указанную строку.

ToString()

Преобразует значение данного экземпляра в String.

ToString(Int32, Int32)

Преобразует значение подстроки этого экземпляра в String.

Явные реализации интерфейса

ISerializable.GetObjectData(SerializationInfo, StreamingContext)

Заполняет объект SerializationInfo данными даты, необходимыми для десериализации текущего объекта StringBuilder.

Применяется к

См. также раздел