Лекция № 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. Как выполнить форматирование строк в соответствии с шаблонами?