Основы работы со строками в Basics (Руководство по программированию в C#)
Обновлен: Ноябрь 2007
Строка является объектом типа String, значением которого является текст. Внутренне текст хранится в коллекции объектов Char с доступом только для чтения, каждый из которых представляет один символ Юникода в UTF-16. В конце строки на языке C# (в отличие от C и C++) имеется символ, заканчивающийся на NULL; поэтому строка C# может содержать любое число внедренных символов NULL ("\0"). Длина строки представляет число символов, независимо от того, образованы ли символы из пар символов-заместителей Юникода или нет. Для доступа к отдельным точкам в строке кода Юникода используется объект StringInfo object.
Строка и System.String
В C# ключевое слово string является псевдонимом свойства String. Поэтому String и string эквивалентны, и пользователи могут использовать любое наиболее предпочтительное для них соглашение по наименованию. Класс String предоставляет множество методов для безопасного создания, обработки и сравнения строк. Кроме того, язык C# перегружает некоторые операторы для упрощения наиболее употребительных операций со строками. Дополнительные сведения о ключевом слове см. в разделе строка (справочник по C#). Дополнительные сведения о типе и его методах см. в разделе String.
Объявление и инициализация строк
Объявление и инициализацию строк можно выполнять различными способами, как показано в следующем примере:
// Declare without initializing.
string message1;
// Initialize to null.
string message2 = null;
// Initialize as an empty string.
// Use the Empty constant instead of the literal "".
string message3 = System.String.Empty;
//Initialize with a regular string literal.
string oldPath = "c:\\Program Files\\Microsoft Visual Studio 8.0";
// Initialize with a verbatim string literal.
string newPath = @"c:\Program Files\Microsoft Visual Studio 9.0";
// Use System.String if you prefer.
System.String greeting = "Hello World!";
// In local variables (i.e. within a method body)
// you can use implicit typing.
var temp = "I'm still a strongly-typed System.String!";
// Use a const string to prevent 'message4' from
// being used to store another string value.
const string message4 = "You can't get rid of me!";
// Use the String constructor only when creating
// a string from a char*, char[], or sbyte*. See
// System.String documentation for details.
char[] letters = { 'A', 'B', 'C' };
string alphabet = new string(letters);
Обратите внимание, что для создания строкового объекта оператор new не используется, за исключением, за исключением случаев инициализации строки массивом символов.
Инициализация строки значением константы Empty приводит к созданию нового объекта String, строка которого имеет нулевую длину. Строковый литерал нулевой длины представляется как "". При инициализации строк значением Empty вместо null снижается вероятности возникновения NullReferenceException. Используйте статический метод IsNullOrEmpty(String), чтобы проверить значение строки перед попыткой обращения к ней.
Неизменность строковых объектов
Строковые объекты являются неизменяемыми: после создания их нельзя изменить. Все методы String и операторы C#, которые, как можно было бы представить, изменяют строку, в действительности возвращают результаты в новый строковый объект. В следующем примере, когда содержимое строк s1 и s2 объединяется в одну строку, две исходные строки не изменяются. Оператор += создает новую строку с объединенным содержимым. Этот новый объект присваивается переменной s1, а исходный объект, который был присвоен строке s1, освобождается для сборки мусора, поскольку ни одна переменная не содержит ссылку на него.
string s1 = "A string is more ";
string s2 = "than the sum of its chars.";
// Concatenate s1 and s2. This actually creates a new
// string object and stores it in s1, releasing the
// reference to the original object.
s1 += s2;
System.Console.WriteLine(s1);
// Output: A string is more than the sum of its chars.
Поскольку "изменением" строки в действительности является созданием новой строки, необходима предосторожность при создании ссылок на строки. Если создать ссылку на строку, а затем "изменить" исходную строку, то ссылка будет по-прежнему указывать на исходный объект, а не на новый объект, который был создан при изменении строки. Это поведение демонстрируется в следующем коде.
string s1 = "Hello ";
string s2 = s1;
s1 += "World";
System.Console.WriteLine(s2);
//Output: Hello
Дополнительные сведения о том, как создавать новые строки, основанные на таких изменениях как операции поиска и замены исходной строки, см. в разделе Практическое руководство. Изменение содержимого строки (Руководство по программированию в C#).
Правильные и буквальные строковые литералы
Правильные строковые литералы используются, если нужно внедрить escape-знаки, предоставляемые языком C#, как показано в следующем примере.
string columns = "Column 1\tColumn 2\tColumn 3";
//Output: Column 1 Column 2 Column 3
string rows = "Row 1\r\nRow 2\r\nRow 3";
/* Output:
Row 1
Row 2
Row 3
*/
string title = "\"The \u00C6olean Harp\", by Samuel Taylor Coleridge";
//Output: "The Æolean Harp", by Samuel Taylor Coleridge
Буквальные строковые литералы используются для удобства и удобства чтения, если текст строки содержит символы обратной косой черты, например в путях к файлу. Поскольку в буквальных строках сохраняются символы новой строки как часть текста строки, они могут использоваться для инициализации многострочных строк. Для встраивания кавычек в буквальную строку используются двойные кавычки. В следующем примере показаны примеры наиболее типичного использования буквальных строк.
string filePath = @"C:\Users\scoleridge\Documents\";
//Output: C:\Users\scoleridge\Documents\
string text = @"My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...";
/* Output:
My pensive SARA ! thy soft cheek reclined
Thus on mine arm, most soothing sweet it is
To sit beside our Cot,...
*/
string quote = @"Her name was ""Sara.""";
//Output: Her name was "Sara."
Escape-последовательности строк
Escape-последовательность |
Имя символа |
Кодировка Юникода |
---|---|---|
\' |
Одинарная кавычка |
0x0027 |
\" |
Двойная кавычка |
0x0022 |
\\ |
Обратная косая черта |
0x005C |
\0 |
Null |
0x0000 |
\a |
ALERT |
0x0007 |
\b |
BACKSPACE |
0x0008 |
\f |
FORM FEED |
0x000C |
\n |
Новая строка |
0x000A |
\r |
Возврат каретки |
0x000D |
\t |
Горизонтальная табуляция |
0x0009 |
\U |
Escape-последовательность Юникода для пар символов-заместителей. |
\Unnnnnnnn |
\u |
Escape-последовательность Юникода |
\u0041 = "A" |
\v |
Вертикальная табуляция |
0x000B |
\x |
Escape-последовательность Юникода аналогична "\u", за исключением строк с переменной длиной. |
\x0041 = "A" |
Примечание. |
---|
Во время компиляции буквальные строки преобразуются в обычные строки со всеми теми же escape-последовательностями. Поэтому, если в окне отладчика просматривается буквальная строка, будут видны escape-символы, добавленные компилятором, а не буквальная версия из исходного кода. Например, буквальная строка @"C:\files.txt" в окне отладчика будет выглядеть как "C:\\files.txt". |
Строки форматов
Строкой формата является строка, содержимое которой можно определить динамически во время выполнения. Строка формата создается при помощи статического метода Format и внедренных местозаполнителей в скобках, которые во время выполнения будут заменены другими значениями. В следующем примере используется строка формата для вывода результатов каждой итерации цикла.
class FormatString
{
static void Main()
{
// Get user input.
System.Console.WriteLine("Enter a number");
string input = System.Console.ReadLine();
// Convert the input string to an int.
int j;
System.Int32.TryParse(input, out j);
// Write a different string each iteration.
string s;
for (int i = 0; i < 10; i++)
{
// A simple format string with no alignment formatting.
s = System.String.Format("{0} times {1} = {2}", i, j, (i * j));
System.Console.WriteLine(s);
}
//Keep the console window open in debug mode.
System.Console.ReadKey();
}
}
Одна перегрузка метода WriteLine в качестве параметра принимает строку формата. Поэтому можно просто внедрить строковый литерал формата без явного вызова метода. Но если используется метод WriteLine для отображения вывода отладочных данных в окно Вывод среды Visual Studio, необходимо явно вызвать метод Format, поскольку WriteLine принимает только строку, а не строку формата. Дополнительные сведения о строках форматах см. в разделе Типы форматирования.
Подстроки
Подстрокой является последовательность символов, содержащихся в строке. Метод Substring используется для создания новой строки на основании части исходной строки. Одно или несколько вхождений подстроки можно найти с использованием метода IndexOf. Метод Replace используется для замены всех вхождений заданной подстроки новой строкой. Так же, как и метод Substring, метод Replace фактически возвращает новую строку и не изменяет исходную строку. Дополнительные сведения см. в разделах Практическое руководство. Поиск строк с помощью строковых методов (руководство по программированию в C#) и Практическое руководство. Изменение содержимого строки (Руководство по программированию в C#).
string s3 = "Visual C# Express";
System.Console.WriteLine(s3.Substring(7, 2));
// Output: "C#"
System.Console.WriteLine(s3.Replace("C#", "Basic"));
// Output: "Visual Basic Express"
// Index values are zero-based
int index = s3.IndexOf("C");
// index = 7
Доступ к отдельным знакам
Нотацию массива можно использовать со значением индекса, чтобы получить доступ только для чтения к отдельным символам, как в следующем примере:
string s5 = "Printing backwards";
for (int i = 0; i < s5.Length; i++)
{
System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"
Если методы String не предоставляют функциональных возможностей, которые необходимы для изменения отдельных символов в строке, можно использовать объект StringBuilder, чтобы изменить отдельные символы "на месте", а затем создать новую строку для сохранения результатов с использованием методов StringBuilder. В следующем примере предположим, что необходимо изменить исходную строку определенным образом, а затем сохранить результаты для дальнейшего использования.
string question = "hOW DOES mICROSOFT wORD DEAL WITH THE cAPS lOCK KEY?";
System.Text.StringBuilder sb = new System.Text.StringBuilder(question);
for (int j = 0; j < sb.Length; j++)
{
if (System.Char.IsLower(sb[j]) == true)
sb[j] = System.Char.ToUpper(sb[j]);
else if (System.Char.IsUpper(sb[j]) == true)
sb[j] = System.Char.ToLower(sb[j]);
}
// Store the new string.
string corrected = sb.ToString();
System.Console.WriteLine(corrected);
// Output: How does Microsoft Word deal with the Caps Lock key?
Строки с нулевыми значениями и пустые строки
Пустая строка — это экземпляр объекта System.String, содержащий 0 знаков. Пустые строки часто используются в различных сценариях программирования, представляя пустое текстовое поле. Для пустых строк можно вызывать методы, потому что такие строки являются допустимыми объектами System.String. Пустые строки инициализируются следующим образом:
string s = String.Empty;
Строки со значениями null (с нулевыми значениями), напротив, не ссылаются на экземпляр объекта System.String, любая попытка вызвать метод на строка со значением null приведет к ошибке NullReferenceException. Однако такие строки можно использовать в операциях объединения и сравнения с другими строками. В следующих примерах показаны некоторые случаи, в которых ссылка на строку со значением null вызывает либо не вызывает исключение:
static void Main()
{
string str = "hello";
string nullStr = null;
string emptyStr = "a";
string tempStr = str + nullStr; // tempStr = "hello"
bool b = (emptyStr == nullStr);// b = false;
string newStr = emptyStr + nullStr; // creates a new empty string
int len = nullStr.Length; // throws NullReferenceException
}
Использование StringBuilder для быстрого создания строк
Операции со строками в .NET в высокой степени оптимизированы и в большинстве случаев значительно не снижают производительность. Однако в некоторых случаях, например, в непрерывных циклах, выполняющихся сотни и тысячи раз, операции со строками могут влиять на производительность. Класс StringBuilder создает строковый буфер, который позволяет повысить производительность, если в программе обрабатывается много строк. Класс StringBuilder также позволяет заново присваивать отдельные знаки, что не поддерживается встроенным строковым типом данных. Например, данный код заменяет содержимое строки без создания новой строки:
System.Text.StringBuilder sb = new System.Text.StringBuilder("Rat: the ideal pet");
sb[0] = 'C';
System.Console.WriteLine(sb.ToString());
System.Console.ReadLine();
//Outputs Cat: the ideal pet
В этом примере объект StringBuilder используется для создания строки из набора числовых типов:
class TestStringBuilder
{
static void Main()
{
System.Text.StringBuilder sb = new System.Text.StringBuilder();
// Create a string composed of numbers 0 - 9
for (int i = 0; i < 10; i++)
{
sb.Append(i.ToString());
}
System.Console.WriteLine(sb); // displays 0123456789
// Copy one character of the string (not possible with a System.String)
sb[0] = sb[9];
System.Console.WriteLine(sb); // displays 9123456789
}
}
Строки, методы расширения и LINQ
Поскольку тип String реализует IEnumerable<T>, можно использовать методы расширения, определенные в классе Enumerable на строках. Чтобы избежать загромождения рабочего пространства, эти методы исключены из IntelliSense для типа String, но тем не менее, они доступны. Можно также использовать выражения запросов LINQ на строках. Дополнительные сведения см. в разделе LINQ и строки.
См. также
Задачи
Практическое руководство. Разделение строк (Руководство по программированию в C#)
Основные понятия
Руководство по программированию в C#