Строки
Обновлен: Ноябрь 2007
Строка C# представляет собой группу одного или нескольких знаков, объявленных с помощью ключевого слова string, которое является ускоренным методом языка C# для класса System.String. В отличие от массивов знаков в C или C++, строки в C# гораздо проще в использовании и менее подвержены ошибкам программирования.
Строковый литерал объявляется с помощью кавычек, как показано в следующем примере.
string greeting = "Hello, World!";
Можно извлекать подстроки и объединять строки, как показано в следующем примере.
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.
Строковые объекты являются неизменяемыми: после создания их нельзя изменить. Методы, работающие со строками, возвращают новые строковые объекты. Поэтому в целях повышения производительности большие объемы работы по объединению строк или другие операции следует выполнять в классе StringBuilder, как показано в далее в примерах кода.
Работа со строками
Escape-знаки
Строки могут содержать escape-знаки, такие как "\n" (новая строка) и "\t" (табуляция). Строка:
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
эквивалентна строке:
Hello
World!
Если требуется добавить в строку обратную косую черту, перед ней нужно поставить еще одну обратную косую черту. Следующая строка
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."
эквивалентна строке
\\My Documents\
Символ @
Символ @ указывает, что при создании строки следует игнорировать escape-знаки и переносы строки. Следующие две строки являются идентичными.
string p1 = "\\\\My Documents\\My Files\\";
string p2 = @"\\My Documents\My Files\";
ToString()
Все встроенные типы данных C# предоставляют метод ToString, преобразующий значение в строку. Этот метод может быть использован для преобразования числовых значений в строки следующим образом.
int year = 1999;
string msg = "Eve was born in " + year.ToString();
System.Console.WriteLine(msg); // outputs "Eve was born in 1999"
Доступ к отдельным знакам
К отдельным знакам, содержащимся в строке, можно получить доступ с помощью таких методов как Substring, Replace, Split и Trim.
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 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?
Доступ к отдельным знакам в строке возможен с помощью индекса, как показано в следующем примере.
string s5 = "Printing backwards";
for (int i = 0; i < s5.Length; i++)
{
System.Console.Write(s5[s5.Length - i - 1]);
}
// Output: "sdrawkcab gnitnirP"
Смена регистра
Чтобы изменить регистр букв в строке (сделать их заглавными или строчными) следует использовать ToUpper() или ToLower(), как показано в следующем примере.
string s6 = "Battle of Hastings, 1066";
System.Console.WriteLine(s6.ToUpper());
// outputs "BATTLE OF HASTINGS 1066"
System.Console.WriteLine(s6.ToLower());
// outputs "battle of hastings 1066"
Сравнения
Наилучшим способом сравнения двух нелокализованных строк является использование метода Equals с StringComparison.Ordinal и StringComparison.OrdinalIgnoreCase.
// Internal strings that will never be localized.
string root = @"C:\users";
string root2 = @"C:\Users";
// Use the overload of the Equals method that specifies a StringComparison.
// Ordinal is the fastest way to compare two strings.
bool result = root.Equals(root2, StringComparison.Ordinal);
Console.WriteLine("Ordinal comparison: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// To ignore case means "user" equals "User". This is the same as using
// String.ToUpperInvariant on each string and then performing an ordinal comparison.
result = root.Equals(root2, StringComparison.OrdinalIgnoreCase);
Console.WriteLine("Ordinal ignore case: {0} and {1} are {2}", root, root2,
result ? "equal." : "not equal.");
// A static method is also available.
bool areEqual = String.Equals(root, root2, StringComparison.Ordinal);
// String interning. Are these really two distinct objects?
string a = "The computer ate my source code.";
string b = "The computer ate my source code.";
// ReferenceEquals returns true if both objects
// point to the same location in memory.
if (String.ReferenceEquals(a, b))
Console.WriteLine("a and b are interned.");
else
Console.WriteLine("a and b are not interned.");
// Use String.Copy method to avoid interning.
string c = String.Copy(a);
if (String.ReferenceEquals(a, c))
Console.WriteLine("a and c are interned.");
else
Console.WriteLine("a and c are not interned.");
Для строковых объектов также существует метод CompareTo(), возвращающий целочисленное значение, которое зависит от того, что одна строка может быть меньше (<) или больше (>) другой. При сравнении строк используется значение Юникода, при этом значение строчных букв меньше, чем значение заглавных.
// Enter different values for string1 and string2 to
// experiement with behavior of CompareTo
string string1 = "ABC";
string string2 = "abc";
int result2 = string1.CompareTo(string2);
if (result2 > 0)
{
System.Console.WriteLine("{0} is greater than {1}", string1, string2);
}
else if (result2 == 0)
{
System.Console.WriteLine("{0} is equal to {1}", string1, string2);
}
else if (result2 < 0)
{
System.Console.WriteLine("{0} is less than {1}", string1, string2);
}
// Output: ABC is less than abc
Чтобы найти строку внутри другой строки следует использовать IndexOf(). IndexOf() возвращает значение -1, если искомая строка не найдена; в противном случае возвращается индекс первого вхождения искомой строки (отсчет ведется с нуля).
// Date strings are interpreted according to the current culture.
// If the culture is en-US, this is interpreted as "January 8, 2008",
// but if the user's computer is fr-FR, this is interpreted as "August 1, 2008"
string date = "01/08/2008";
DateTime dt = Convert.ToDateTime(date);
Console.WriteLine("Year: {0}, Month: {1}, Day: {2}", dt.Year, dt.Month, dt.Day);
// Specify exactly how to interpret the string.
IFormatProvider culture = new System.Globalization.CultureInfo("fr-FR", true);
// Alternate choice: If the string has been input by an end user, you might
// want to format it according to the current culture:
// IFormatProvider culture = System.Threading.Thread.CurrentThread.CurrentCulture;
DateTime dt2 = DateTime.Parse(date, culture, System.Globalization.DateTimeStyles.AssumeLocal);
Console.WriteLine("Year: {0}, Month: {1}, Day {2}", dt2.Year, dt2.Month, dt2.Day);
/* Output (assuming first culture is en-US and second is fr-FR):
Year: 2008, Month: 1, Day: 8
Year: 2008, Month: 8, Day 1
*/
Разделение строки на подстроки
Разделение строки на подстроки, аналогичное разделению предложения на отдельные слова, является распространенной задачей в программировании. Метод Split() получает массив разделителей типа char (например, разделителем может быть пробел) и возвращает массив подстрок. Доступ к массиву можно получить только с помощью foreach, как показано в следующем примере.
string numString = "1287543"; //"1287543.0" will return false for a long
long number1 = 0;
bool canConvert = long.TryParse(numString, out number1);
if (canConvert == true)
Console.WriteLine("number1 now = {0}", number1);
else
Console.WriteLine("numString is not a valid long");
byte number2 = 0;
numString = "255"; // A value of 256 will return false
canConvert = byte.TryParse(numString, out number2);
if (canConvert == true)
Console.WriteLine("number2 now = {0}", number2);
else
Console.WriteLine("numString is not a valid byte");
decimal number3 = 0;
numString = "27.3"; //"27" is also a valid decimal
canConvert = decimal.TryParse(numString, out number3);
if (canConvert == true)
Console.WriteLine("number3 now = {0}", number3);
else
Console.WriteLine("number3 is not a valid decimal");
Этот код выводит каждое слово в отдельной строке, как показано в следующем примере.
The
cat
sat
on
the
mat.
Использование класса StringBuilder
Класс StringBuilder создает строковый буфер, который позволяет повысить производительность, если в программе обрабатывается много строк. Класс StringBuilder также позволяет заново присваивать отдельные знаки, что не поддерживается встроенным строковым типом данных.
В следующем примере создается объект StringBuilder и его содержимое последовательно добавляется с помощью метода Append.
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
}
}
См. также
Задачи
Практическое руководство. Создание многострочных строковых литералов
Практическое руководство. Поиск строки в массиве строк
Практическое руководство. Поиск в строке