Лекция № 2
Тема: "Работа со строками"
План
1. Создание строк
2. Методы строк
3. Форматирование строк в соответствии с шаблонами
1. Создание строк
Довольно большое количество задач, которые могут встретиться при разработке приложений, так или иначе связано с обработкой строк - парсинг веб-страниц, поиск в тексте, какие-то аналитические задачи, связанные с извлечением нужной информации из текста и т.д. Поэтому в этом плане работе со строками уделяется особое внимание.
В языке C# строковые значения представляет тип string, а вся функциональность работы с данным типом сосредоточена в классе System.String. Собственно string является псевдонимом для класса System.String. Объекты этого класса представляют текст как последовательность символов Unicode. Максимальный размер объекта String может составлять в памяти 2 ГБ, или около 1 миллиарда символов.
Создавать строки можно, как используя переменную типа string и присваивая ей значение, так и применяя один из конструкторов класса String:
//способы описания и инициализации строк
string s1 = "hello";
string s2 = null;
string s3 = new String('a', 6); // результатом будет строка "aaaaaa"
string s4 = new String(new char[]{'w', 'o', 'r', 'l', 'd'}); //результатом будет строка "world"
Конструктор String имеет различное число версий. Так, вызов конструктора new String('a', 6) создаст строку "aaaaaa". И так как строка представляет ссылочный тип, то может хранить значение null.
Строка как набор символов
Применяя индексатор, мы можем обратиться к строке как к массиву символов и получить по индексу любой из ее символов. При этом нумерация символов начинается с 0.
Напоминание: в соответствии с синтаксисом языка C строка берется в двойные кавчки, а символ - в одинарные.
string s1 = "hello";
char ch1 = s1[1]; // символ 'e'
Используя свойство Length, как и в обычном массиве, можно получить длину строки:
int len = s1.Length; //5 (в строке 5 символов)
2. Методы строк
Основная функциональность класса String раскрывается через его методы, среди которых можно выделить следующие:
- Compire(string s1, string s2) //сравнивает две строки
Если s1<s2, метод возвращает значение меньше 0, если s1>s2 - больше 0, если s1==s2 - возвращает 0. Например:
string s1 = "hello";
string s2 = "world";
//сравниваем строки и записываем результат в переменную
int result = String.Compare(s1, s2);
//проверяем полученный результат сравнения
if (result<0)
MessageBox.Show("Строка s1 стоит перед строкой s2");
else if (result > 0)
MessageBox.Show("Строка s1 стоит после строки s2");
else
MessageBox.Show("Строки s1 и s2 идентичны");
Если строки нужно проверить на равенство (==) или неравенство (!=), то вместо метода Compire() модно использовать сравнение напрямую.
Например:
string s1 = "hello";
string s2 = "world";
//сравниваем строки и записываем результат в переменную
int result = String.Compare(s1, s2);
//проверяем полученный результат сравнения
if (result==0)
MessageBox.Show("Строки s1 и s2 идентичны");
else
MessageBox.Show("Строки s1 и s2 не идентичны");
Этот же пример при сравнении напрямую:
string s1 = "hello";
string s2 = "world";
//сравниваем строки
if (s1==s2)
MessageBox.Show("Строки s1 и s2 идентичны");
else
MessageBox.Show("Строки s1 и s2 не идентичны");
- Contains(char ch) //определяет, содержится ли символ в строке
Contains(string s) //определяет, содержится ли подстрока в строке
Метод возвращает true, если содержится и false - если нет. Например:
string s = "hello world !!!";
//проверим наличие символа 'r' в тексте
if (s.Contains('r'))
MessageBox.Show("Строка содержит символ 'r'");
else
MessageBox.Show("Строка не содержит символ 'r'");
//проверим наличие слова "world" в тексте
if (s.Contains("world"))
MessageBox.Show("Строка содержит слово 'world'");
else
MessageBox.Show("Строка не содержит слово 'world'");
- String.Concat(string s1, string s2, ..., string sN) //соединяет строки
Например:
string s1 = "hello";
string s2 = "world";
string s3 = String.Concat(s1," ", s2, "!!!"); // результат: строка "hello world!!!"
//аналогом данной функции является обычное сложение строк
string s4=s1+" "+s2+"!!!";
- EndsWith(string s) //определяет, совпадает ли конец строки с подстрокой s
Если совпадает, то метод возвращает true, в противном случае - false. Например,
string s1 = "hello";
//проверяем, заканчивается ли строка на "lo"
if (s1.EndsWith("lo"))
MessageBox.Show("Строка заканчивается на 'lo'");
else
MessageBox.Show("Строка не заканчивается на 'lo'");
- IndexOf (char ch[, int pos, [int count]])// находит индекс первого вхождения символа
IndexOf (string s[, int pos, [int count]])// находит индекс первого вхождения подстроки
Параметр pos - задает номер символа, с которого нужно начинать поиск (не обязательный, по умолчанию с начала текста)
Параметр count - задает количество символов, среди которых нужно выполнять поиск (не обязательный, по умолчанию до конца текста).
Результатом работы метода является номер позиции символа, с которой начинается найденный фрагмент. Если фрагмент не найден - метод возвращает -1.
Например:
string s="hello world";
s.IndexOf('o') //вернет значение 4 (поиск с начала текста (hello world))
s.IndexOf('o',6); //вернет 7 (поиск с 6 символа (hello world))
s.IndexOf("world") //вернет значение 6 (поиск с начала текста (hello world))
s.IndexOf("world",8) //вернет значение -1 (начиная с позиции 8 слова world не обнаружено (hello world))
- Insert(int pos, string s) //вставляет в строку подстроку, начиная с позиции pos
Результат работы метода должен быть присвоен переменной. Например:
string s="hello world";
s=s.Insert(6,"beautiful "); //вставляем слово в 6 позицию (hello world)
//результат "hello beautiful world"
- String.Join(string str, obj [] values) //формирует строку, стоящую из элементов массива values, разделенных символами str
Результат работы метода должен присваиваться строковой переменной. Массив может быть любого типа, метод автоматически конвертирует все элементы в текст. Например:
//опишем массив строк
string[] arrStr = {"One","Two","Three","Four"};
//опишем переменную для результата
string rez="";
//объединим элементы массива через пробел
rez=String.Join(" ", arrStr); //получим "One Two Three Four"
//опишем массив целых чисел
int[] arrInt = {1,2,3,4 };
//опишем переменную для результата
string rez2="";
//объединим элементы массива через тире
rez2=String.Join(" - ", arrInt); //получим "1 - 2 - 3 - 4"
Замечание: обратите внимание, что метод Join() вызывается не для строковой переменной, а для класса String.
- LastIndexOf (char ch[, int pos, [int count]]) //находит индекс последнего вхождения символа
LastIndexOf (string s[, int pos, [int count]]) //находит индекс последнего вхождения подстроки
Параметр pos - задает номер символа, с которого нужно начинать поиск (не обязательный, по умолчанию с начала текста)
Параметр count - задает количество символов, среди которых нужно выполнять поиск (не обязательный, по умолчанию до конца текста).
Результатом работы метода является номер позиции символа, с которой начинается найденный фрагмент. Если фрагмент не найден - метод возвращает -1.
Например:
string s="hello world";
s.LastIndexOf('o') //вернет значение 7 (поиск с начала текста (hello world))
s.LastIndexOf('o',0,5); //вернет 4 (поиск с 0 символа длиной 5 символов (hello world))
s.LastIndexOf("world") //вернет значение 6 (поиск с начала текста (hello world))
s.LastIndexOf("world",8) //вернет значение -1 (начиная с позиции 8 слова world не обнаружено (hello world))
- Remove(int pos[, int count]) //удаляет из строки текст, начиная с позиции pos длиной count символов
Параметр count - задает количество символов для удаления. Данный параметр не обязательный. Если он не указан, то удаление происходит до конца текста. Результат работы метода нужно присваивать переменной. Например:
string s = "Hello World";
//с позиции 0 удалим 6 символов
s = s.Remove(0, 6); //результат "World"
//восстанавливаем текст
string s = "Hello World";
//с позиции 5 удалим текст до конца
s = s.Remove(5); //результат "Hello"
- Replace(char oldChar, char newChar) //замещает в строке символ oldChar на символ newChar
Replace(string oldStr, char newStr) //замещает в строке подстроку oldStr на символ newStr
Метод замещает все найденные символы или подстроки. Результат работы должен быть присвоен переменной. Например:
string s="hello world";
//заменяем строчную 'o' на прописную 'O'
s=s.Replace('o','O'); //результат "hellO wOrld"
//восстанавливаем текст
s="hello world";
//заменяем "hello" на "bye"
s=s.Replace("hello","bye"); //результат "bye world"
- Split(char [] arrCh[, StringSplitOptions.RemoveEmptyEntries] //разделяет строку на элементы массива строк в соответствии разделителями, заданными в массиве символов arrCh
Split(string [] arrStr[, StringSplitOptions.RemoveEmptyEntries] //разделяет строку на элементы массива строк в соответствии разделителями, заданными в массиве строк arrStr
Результат работы метода присваивается строковому массиву. Необязательный параметр StringSplitOptions.RemoveEmptyEntries указывает на то, что пустые элементы в результирующий массив добавлять не нужно. Например:
//зададим исходный текст
string s="Это строка, предназначенная для разделения (методом Split)";
//опишем строковый массив для результата
string[] rez;
//необходимо получить массив всех слов текста
//видим, что слова в тексте разделяются пробелом, запятой и круглыми скобками
//внутри метода в качестве первого аргумента создадим символьный массив с этими разделителями
//также укажем второй параметр запрета добавления пустых строк в массив
rez=s.Split(new char [] {' ',',','(',')'},StringSplitOptions.RemoveEmptyEntries);
//в цикле по массиву rez выведем его элементы
foreach (string a in rez)
MessageBox.Show(a);
Допустим, что слова в тексте разделяются не одним символом, а сочетанием из нескольких символов. В этом случае массив разделителей нужно описывать не символьным, а строковым.
//зададим исходный текст. Слова разделены сочетаниями "=>" или "<!-", или "-->"
string s="<!-Это=>строка=>предназначенная=>для=>разделения=>методом=>Split-->";
//опишем строковый массив для результата
string[] rez;
//необходимо получить массив всех слов текста
//внутри метода в качестве первого аргумента создадим строковый массив с разделителями
//также укажем второй параметр запрета добавления пустых строк в массив
rez=s.Split(new string [] {"=>","<!-","-->"},StringSplitOptions.RemoveEmptyEntries);
//в цикле по массиву rez выведем его элементы
foreach (string a in rez)
MessageBox.Show(a);
- Substring(int pos[,int count]) //извлекает из строки подстроку, начиная с pos, длиной count
Параметр count не обязательный. Если его не указать то извлекается фрагмент с pos и до конца текста. Результат работы метода нужно присваивать строковой переменной. Например:
string s = "hello world";
string rez = s.Substring(6); //вырезаем текст с 6 символа (результат "world")
string rez1 = s.Substring(2,3); //вырезаем текст со 2 символа длиной 3 символа (результат "llo")
- StartsWith(string s) //определяет начинается ли строка на заданный фрагмент s
Если начинается, то метод возвращает true, в противном случае - false. Например:
string s = "hello world";
//проверим, начинается ли строка на "hel"
if (s.StartsWith("hel"))
MessageBox.Show("Строка начинается на 'hel'");
else
MessageBox.Show("Строка не начинается на 'hel'");
- ToLower() //переводит все символы строки в нижний регистр
Метод не имеет параметров. Результат должен присваиваться переменной. Например:
string s = "Hello World";
s=s.ToLower(); //результат "hello world"
- ToUpper() //переводит все символы строки в верхний регистр
Метод не имеет параметров. Результат должен присваиваться переменной. Например:
string s = "Hello World";
s=s.ToUpper(); //результат "HELLO WORLD"
- Trim([char [] arrCh]) //удаляет начальные и конечные символы, заданные массивом символов arrCh
TrimStart(char [] arrCh) //удаляет начальные символы, заданные массивом символов arrCh
TrimEnd(char [] arrCh) //удаляет конечные символы, заданные массивом символов arrCh
Метод Trim() может быть вызван без параметров. В этом случае он удаляет начальные и конечные пробелы.
Методы TrimStart() и trimEnd() обязательно имеют входной параметр arrCh.
Результат работы методов должен присваиваться переменной. Например:
//зададим текст с начальными и конечными пробелами
string s = " Hello World ";
s=s.Trim(); //результат "Hello World"
//вызовем метод с удалением символов
s=s.Trim(new char [] {'H','d'}); //результат "ello Worl"
//пусть текст заканчивается на '.'
s="Hello World.";
//удалим ее
//если нужно удалить один символ, то его можно указать без описания массива
s.TrimEnd('.'); //результат "Hello World"
3. Форматирование строк
Для форматированиястрок существует специальный метод вида:
String.Format("templates", args)
Данный метод вызывается не для строковой переменной, а для класса String.
Параметр templates представляет собой строку, содержащую как обычный текст, так и метки для размещения форматированного текста. Каждая метка записывается в формате
{a,[b:]с[d]}
где a - номер аргумента в строке форматирования. Может задаваться отрицательным (выравнивание по левому краю) или положительным (выравнивание по правому краю).
b - ширин вывода аргумента. ;
с - задает описатель формата вывода;
d - необязательный параметр, задающий длину или точность вывода.
Параметр args - это перечень значений через запятую, которые нужно вывести в заданном формате.
Рассмотрим основные описатели метода.
|
C / c |
Задает формат денежной единицы, можно указать количество десятичных разрядов после запятой |
|
D / d |
Целочисленный формат, можно указать минимальное количество цифр |
|
E / e |
Экспоненциальное представление числа, можно указать количество десятичных разрядов после запятой |
|
F / f |
Формат дробных чисел с фиксированной точкой, можно указать количество десятичных разрядов после запятой |
|
G / g |
Задает более короткий из двух форматов: F или E |
|
N / n |
Также задает формат дробных чисел с фиксированной точкой, можно указать количество разрядов после запятой |
|
P / p |
Задает отображения знака процентов рядом с число, можно указать количество десятичных разрядов после запятой |
|
S / s |
Задает формат вывода текста, можно указать дину текста в символах |
|
X / x |
Шестнадцатеричный формат числа |
|
# |
Любая цифра |
Примеры форматирования
1. Форматирование валюты
Для форматирования валюты используется описатель "C":
double number = 23.7;
//форматируем значение number в денежный формат шириной 10 знаков
//выравнивание по правому краю
string result = String.Format("{0,10:C}", number); //" 23.7р."
//форматируем значение number в денежный формате
//шириной 10 знаков выравнивание по левому краю
//с точностью 2 знака
string result2 = String.Format("{0,-10:C2}", number); //"23.70р. "
2. Форматирование целых чисел
Для форматирования целочисленных значение применяется описатель "d":
int number = 23;
//форматируем значение number в целый формат шириной 6 символов
//выравнивание по правому краю
string result = String.Format("{0,6:d}", number); //" 23"
//форматируем значение number в целый формат шириной 6 символов
//выравнивание по левому краю
string result2 = String.Format("{0,-6:d}", number); //"23 "
3. Форматирование дробных чисел
Для форматирования дробных чисел используется описатель F, число после которого указывает, сколько знаков будет использоваться после разделителя между целой и дробной частью. Если исходное число - целое, то к нему добавляются разделитель и нули.
int number = 23;
//форматируем целое значение number в дробный формат
//шириной 8 символов с выравнивание по правому краю
string result = String.Format("{0,8:f}", number); //" 23,00"
//форматируем дробное значение number2 в дробный формат
//шириной 8 символов с выравнивание по левому краю с точностью 4 знака
double number2 = 45.08;
string result2 = String.Format("{0,-8:f4}", number2); //"45,0800 "
//форматируем дробное значение number3 в дробный формат
//шириной 10 знаков с выравнивание по правому краю с точностью 1 знак
double number3 = 25.07;
string result3 = String.Format("{0,10:f1}", number3); // " 25,1"
4. Настраиваемые форматы
Используя знак #, можно настроить формат вывода любой ширины и любой точности. Например, нам надо вывести некоторое число в формате телефона +х (ххх)ххх-хх-хх:
long number = 19876543210;
string result = String.Format("{0:+# (###) ###-##-##}", number); // +1 (987) 654-32-10
5. Комбинирование текста и форматов вывода
При задании формата вывода кроме символов форматирования Вы можете использовать произвольный текст, который будет возвращен в том виде, в котором он задан в методе. Кроме этого Вы можете отформатировать несколько значений переменных в разные форматы.
//опишем два вещественных числа
double x=10.5, y=2.56;
//формируем шаблон вывода с использованием текстовых подсказок
//каждый аргумент будет подставлен на метку со своим номером
string result = String.Format("Сумма двух чисел: {0,5:F} + {1,5:F} = {2,5:F}",x,y,x+y);
string f="Иванов", i="Сергей";
double p=9500;
string result2=String.Format("Фамилия: {0,15:s}; Имя: {1,15:s}, Премия; {2,8:f}",f,i,p);
Метод ToString()
Как известно, любой объект имеет метод ToString(), который не только получает строковое описание объекта, но и может осуществлять форматирование. Он поддерживает те же описатели, что используются в методе Format(). При этом ширину вывода указать нельзя. Описатель формат вывода передается в метод в качестве параметра:
long number = 19876543210;
string result = number.ToString("+# (###) ###-##-##"); // +1 (987) 654-32-10
double money = 24.8;
string result2 = money.ToString("C2"); //24,80р.
double number2 = 45.08;
string result3 = number2.ToString("f4"); //45,0800
Замечание: все рассмотренные выше возможности по работе со строками описывались на основе строковых переменных. Однако, они также могут применяться и к текстовым свойствам компонент, например к свойству Text.
Вопросы для самопроверки
1. Как описать строковую переменную, обратиться к символу строки, узнать длину строки?
2. Какие существуют методы по работе со строками ?
3. Как выполнить форматирование строк в соответствии с шаблонами?