Лекція 6. Робота з рядками

 

У класі System.String надається набір методів для визначення довжини символьних даних, пошуку підрядка в поточному рядку, перетворення символів з верхнього регістру в нижній і навпаки, і т.д. Далі ми розглянемо цей клас більш детально.

Поле, індексатор і властивість класу String

У класі String визначено єдине поле:

public static readonly string Empty;

Поле Empty означає порожній рядок, тобто такий рядок, який не містить символи. Цим він відрізняється від порожнього посилання типу String, яке просто робиться на неіснуючий об'єкт.

Крім цього, в класі String визначено єдиний індексатор, доступний тільки для читання:

public char this[int index] { get; }

Цей індексатор дозволяє отримати символ за вказаним з індексом. Індексація рядків, як і масивів, починається з нуля. Об'єкти типу String відрізняються постійністю і не змінюються, тому цілком логічно, що в класі String підтримується індексатор, доступний тільки для читання.

І нарешті, в класі String визначена єдина властивість, доступна тільки для читання:

public int Length { get; }

Властивість Length повертає кількість символів в рядку. У прикладі нижче показано використання індексатора і властивості Length:

using System;

 

class Example

{

    static void Main()

    {

        string str = "Простий рядок";

 

        // Отримати довжину рядка і 6 й символ в рядку використовуючи індексатор

        Console.WriteLine("Довжина рядка - {0}, 6й символ - '{1}'",

            str.Length, str[5]);

    }

}

Оператори класу String

У класі String перевантажуються два наступних оператора: == і! =. Оператор == служить для перевірки двох символьних рядків на рівність. Коли оператор == застосовується до посилань на об'єкти, він зазвичай перевіряє, чи робляться обидві посилання на один і той же об'єкт. А коли оператор == застосовується до посилань на об'єкти типу String, то на предмет рівності порівнюється вміст самих рядків. Те саме стосується і до оператора! =. Коли він застосовується до посилань на об'єкти типу String, то на предмет нерівності порівнюється вміст самих рядків. У той же час інші оператори відношення, в тому числі <і> =, порівнюють посилання на об'єкти типу String таким же чином, як і на об'єкти інших типів. А для того щоб перевірити, чи є один рядок більше іншого, слід викликати метод Compare (), визначений в класі String.

Як стане ясно далі, у багатьох видах порівняння символьних рядків використовуються відомості про культурне середовище. Але це не відноситься до операторів == і! =. Адже вони просто порівнюють порядкові значення символів в рядках. (Іншими словами, вони порівнюють двійкові значення символів, які не видозмінені нормами культурного середовища, тобто регіональними стандартами.) Отже, ці оператори виконують порівняння рядків без урахування регістру і налаштувань культурного середовища.

Методи класу String

У таблиці наведено деякі найбільш цікаві методи цього класу, згруповані за призначенням:

Методи роботи з рядками

Метод

Структура та перезавантажені версії

Призначення

Порівняння рядків

Compare()

public static int Compare(string strA, string strB)

public static int Compare(string strA, string strB, bool ignoreCase)

public static int Compare(string strA, string strB, StringComparison comparisonType)

public static int Compare(string strA, string strB, bool ignoreCase, CultureInfo culture)

Статичний метод, порівнює рядок strA з рядком strB. Повертає позитивне значення, якщо рядок strA більше рядка strB; від'ємне значення, якщо рядок strA менше рядка strB; і нуль, якщо рядки strA і strB рівні. Порівняння виконується з урахуванням регістра і культурного середовища.

Якщо параметр ignoreCase приймає логічне значення true, то при порівнянні не враховуються відмінності між прописним і рядковим варіантами букв. В іншому випадку ці відмінності враховуються.

Параметр comparisonType визначає конкретний спосіб порівняння рядків.


Клас CultureInfo визначено в просторі імен System.Globalization.

public static int Compare(string strA, int indexA, string strB, int indexB, int length)

public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase)

public static int Compare(string strA, int indexA, string strB, int indexB, int length, StringComparison comparisonType)

public static int Compare(string strA, int indexA, string strB, int indexB, int length, bool ignoreCase, CultureInfo culture)

Порівнює частини рядків strA і strB. Порівняння починається з рядкових елементів strA [indexA] і strB [indexB] і включає кількість символів, які визначаються параметром length. Метод повертає позитивне значення, якщо частина рядка strA більше частини рядка strB; від'ємне значення, якщо частина рядка strA менше частини рядка strB; і нуль, якщо порівнювані частини рядків strA і strB рівні. Порівняння виконується з урахуванням регістра і культурного середовища.

CompareOrdinal()

public static int CompareOrdinal(string strA, string strB)

public static int CompareOrdinal(string strA, int indexA, string strB, int indexB, int count)

Робить те ж, що і метод Compare (), але без урахування локальних налаштувань

CompareTo()

public int CompareTo(object value)

Порівнює викликаючий рядок зі рядковим поданням об'єкта value. Повертає позитивне значення, якщо викликаючий рядок більше рядка value; від'ємне значення, якщо викликаючий рядок менше рядка value; і нуль, якщо порівнювані рядки рівні

public int CompareTo(string strB)

Порівнює викликаючий рядок з рядком strB

Equals()

public override bool Equals(object obj)

Повертає логічне значення true, якщо викликаючий рядок містить ту ж послідовність символів, що і рядкове представлення об'єкту obj. Виконується порядкове порівняння з урахуванням регістра, але без урахування культурного середовища

public bool Equals(string value)

public bool Equals(string value, StringComparison comparisonType)

Повертає логічне значення true, якщо викликаючий рядок містить ту ж послідовність символів, що і рядок value. Виконується порядкове порівняння з урахуванням регістра, але без урахування культурного середовища. Параметр comparisonType визначає конкретний спосіб порівняння рядків

public static bool Equals(string a, string b)

public static bool Equals(string a, string b, StringComparison comparisonType)

Повертає логічне значення true, якщо рядок a містить ту ж послідовність символів, що і рядок b. Виконується порядкове порівняння з урахуванням регістра, але без урахування культурного середовища. Параметр comparisonType визначає конкретний спосіб порівняння рядків

Конкатенація (з’єднання) рядків

Concat()

public static string Concat(string str0, string str1);

public static string Concat(params string[] values);

Комбінує окремі екземпляри рядків в один рядок (конкатенація)

Пошук в рядку

Contains()

public bool Contains(string value)

Метод, який дозволяє визначити, чи міститься в рядку певний підрядок (value)

StartsWith()

public bool StartsWith(string value)

public bool StartsWith(string value, StringComparison comparisonType)

Повертає логічне значення true, якщо викликаючий рядок починається з підрядка value. В іншому випадку повертається логічне значення false. Параметр comparisonType визначає конкретний спосіб виконання пошуку

EndsWith()

public bool EndsWith(string value)

public bool EndsWith(string value, StringComparison comparisonType)

Повертає логічне значення true, якщо викликаючий рядок закінчується підрядком value. В іншому випадку повертає логічне значення false. Параметр comparisonType визначає конкретний спосіб пошуку

IndexOf()

public int IndexOf(char value)

public int IndexOf(string value)

Знаходить перше входження заданого підрядка або символу в рядку. Якщо шуканий символ або підрядок не знайдено, то повертається значення -1

public int IndexOf(char value, int startIndex)

public int IndexOf(string value, int startIndex)

public int IndexOf(char value, int startIndex, int count)

public int IndexOf(string value, int startIndex, int count)

Повертає індекс першого входження символу або підрядка value в викликаючому рядку. Пошук починається з елемента, що вказується по індексу startIndex, і містить число входжень, що визначаються параметром count (якщо вказаний). Метод повертає значення -1, якщо шуканий символ або підрядок не виявлено

LastIndexOf()

Перегруженные версии аналогичны методу IndexOf()

Те ж, що IndexOf, але знаходить останнє входження символу або підрядка, а не перше

IndexOfAny()

public int IndexOfAny(char[] anyOf)

public int IndexOfAny(char[] anyOf, int startIndex)

public int IndexOfAny(char[] anyOf, int startIndex, int count)

Повертає індекс першого входження будь-якого символу з масиву anyOf, знайденого в викликаючому рядку. Пошук починається з елемента, що вказується по індексу startIndex, і містить число елементів, що визначаються параметром count (якщо вони вказані). Метод повертає значення -1, якщо не виявлено збіг ні з одним із символів з масиву anyOf. Пошук здійснюється порядковим способом

LastIndexOfAny

Перегруженные версии аналогичны методу IndexOfAny()

Повертає індекс останнього входження будь-якого символу із масиву any Of, знайденого в викликаючому рядку

Поділ та з’єднання рядків

Split

public string[] Split(params char[] separator)

public string[] Split(params char[] separator, int count)

Метод, який повертає масив string з присутніми в даному рядку підрядками, які відокремлюються один від одного розділювачами із зазначеного масиву char або string.

У першій формі методу Split () викликаючий рядок розділяється на складові частини. У підсумку повертається масив, що містить підрядки, отримані із викликаючого рядка. Символи, що розділяють ці підрядки, передаються в масиві separator. Якщо масив separator порожній або посилається на порожній рядок, то як роздільник підрядків використовується пропуск. А в другій формі даного методу повертається кількість підрядків, що визначаються параметром count.

public string[] Split(params char[] separator, StringSplitOptions options)

public string[] Split(string[] separator, StringSplitOptions options)

public string[] Split(params char[] separator, int count, StringSplitOptions options)

public string[] Split(string[] separator, int count, StringSplitOptions options)

У двох перших формах методу Split () викликаючий рядок розділяється на частини і повертається масив, що містить підрядки, отримані із викликаючого рядка. Символи, що розділяють ці підрядки, передаються в масиві separator. Якщо масив separator порожній, то як роздільник використовується пропуск. А в третій і четвертій формах даного методу повертається кількість рядків, що обмежується параметром count.

Але у всіх формах параметр options означає конкретний спосіб обробки порожніх рядків, які утворюються в тому випадку, якщо два роздільника опиняються поруч. У перерахуванні StringSplitOptions визначаються тільки два значення: None і RemoveEmptyEntries. Якщо параметр options приймає значення None, то порожні рядки включаються в кінцевий результат поділу початкового рядка. А якщо параметр options приймає значення RemoveEmptyEntries, то порожні рядки виключаються із кінцевого результату поділу початкового рядка.

Join()

public static string Join(string separator, string[] value)

public static string Join(string separator, string[] value, int startIndex, int count)

Будує новий рядок, комбінуючи вміст масиву рядків.
У першій формі методу Join () повертається рядок, що складається із склеюваних підрядків, переданих в масиві value. У другій формі також повертається рядок, що складається із підрядків, переданих в масиві value, але вони склеюються в визначеній кількості count, починаючи з елемента масиву value [startIndex]. В обох формах кожний наступний рядок відділяється від попереднього розділовим рядком, який визначається параметром separator.

Заповнення і обрізання рядків

Trim()

public string Trim()

public string Trim(params char[] trimChars)

Метод, який дозволяє видаляти всі входження певного набору символів з початку і кінця поточного рядка.

У першій формі методу Trim () із викликаючого рядка видаляються початкові і кінцеві пробіли. А в другій формі цього методу видаляються початкові і кінцеві входження в викликаючому рядку символів із масиву trimChars. В обох формах повертається отриманий в результаті рядок.

PadLeft()

public string PadLeft(int totalWidth)

public string PadLeft(int totalWidth, char paddingChar)

Дозволяє доповнити рядок символами зліва.

У першій формі методу PadLeft () дописуються пробіли з лівого боку викликаючого рядка, щоб її загальна довжина стала рівною значенню параметра totalWidth. А в другій формі даного методу символи, що передаються  параметром paddingChar, дописуються з лівого боку викликаючого рядка, щоб його загальна довжина стала рівною значенню параметра totalWidth. В обох формах повертається отриманий в результаті рядок. Якщо значення параметра totalWidth менше довжини викликаючого рядка, то повертається копія незміненого викликаючого рядка.

PadRight()

Аналогічно PadLeft()

Дозволяє доповнити рядок символами з права.

Вставка, видалення та заміна рядків

Insert()

public string Insert(int startIndex, string value)

Використовується для вставки одного рядка в інший, де value позначає рядок, що вставляється в викликаючий рядок по індексу startIndex. Метод повертає отриманий в результаті рядок.

Remove()

public string Remove(int startIndex)

public string Remove(int startIndex, int count)

Використовується для видалення частини рядка. У першій формі методу Remove () видалення виконується, починаючи з місця, зазначеного вище по індексу startIndex, і продовжується до кінця рядка. А в другій формі даного методу із рядка віддаляється кількість символів, яке визначається параметром count, починаючи з місця, зазначеного вище по індексу startIndex.

Replace()

public string Replace(char oldChar, char newChar)

public string Replace(string oldValue, string newValue)

Використовується для заміни частини рядка. У першій формі методу Replace () всі входження символу oldChar в викликаючому рядку замінюються символом newChar. А в другій формі даного методу всі входження рядка oldValue в викликаючого рядка замінюються рядком newValue.

Зміна реєстру

ToUpper()

public string ToUpper()

Записує викликаючий рядок великими літерами.

ToLower()

public string ToLower()

Записує викликаючий рядок маленькими літерами.

Отримання підрядка з рядка

Substring()

public string Substring(int startIndex)

public string Substring(int startIndex, int length)

У першій формі методу Substring () підрядок витягується, починаючи з місця, що задається параметром startIndex, і до кінця викликаючого рядка. А в другій формі даного методу витягується підрядок, що складається із кількості символів, що задаються параметром length, починаючи з місця, що задається параметром startIndex.

 

Трохи про порівняння рядків в C #

Ймовірно, із усіх операцій обробки символьних рядків найчастіше виконується порівняння одного рядка з іншим. Перш ніж розглядати будь-які методи порівняння рядків, слід підкреслити наступне: порівняння рядків може бути виконано в середовищі .NET Framework двома основними способами:

·         По-перше, порівняння може враховувати звичаї та норми окремого культурного середовища, які часто являють собою налаштування культурного середовища, що вступають в силу при виконанні програми. Це стандартна поведінка деяких, хоча і не всіх методів порівняння.

·         І по-друге, порівняння може бути виконано незалежно від налаштувань культурного середовища тільки за порядковими значеннями символів, складаючих рядок. Взагалі кажучи, при порівнянні рядків без урахування культурного середовища використовується лексикографічний порядок (та лінгвістичні особливості), щоб визначити, чи є один рядок більше, менше або дорівнює іншому рядку. При порядковому порівнянні рядка просто порівнюються невидозмінені значення кожного символу.

В силу відмінностей способів порівняння рядків з урахуванням культурного середовища та порядкового порівняння, а також наслідків кожного такого порівняння настійливо рекомендується керуватися найкращими методиками, запропонованими в даний час корпорацією Microsoft. Адже вибір невірного способу порівняння рядків може привести до неправильної роботи програми, коли вона експлуатується в середовищі, що відрізняється від того, в якому вона розроблена..

Вибір способу порівняння символьних рядків представляє собою досить відповідальне рішення. Як правило і без будь-яких винятків, слід вибирати порівняння рядків з урахуванням культурного середовища, якщо це робиться для цілей відображення результату користувачеві (наприклад, для виведення на екран ряду рядків, відсортованих в лексикографічному порядку). Але якщо рядки містять фіксовану інформацію, не призначену для видозміни з урахуванням відмінностей в культурних середовищах, наприклад, ім'я файлу, ключове слово, адреса веб-сайту або значення, пов'язане із забезпеченням безпеки, то слід вибрати порядкове порівняння рядків.

У класі String надаються найрізноманітніші методи порівняння рядків, які перераховані в таблиці вище. Найбільш універсальним серед них є метод Compare (). Він дозволяє порівнювати два рядки повністю або частково, з урахуванням або без урахування регістру, способу порівняння, що визначається параметром типу StringComparison, а також відомостей про культурне середовище, що надаються за допомогою параметра типу CultureInfo.

Тобто перенавантажувані варіанти методу Compare (), які не містять параметр типу StringComparison, виконують порівняння символьних рядків з урахуванням регістра і культурного середовища. А в тих, перевантажених його варіантах, які не містять параметр типу CultureInfo, відомості про культурне середовище визначаються поточним середовищем виконання.

Тип StringComparison являє собою перелік, в якому визначаються значення, наведені в таблиці нижче. Використовуючи ці значення, можна організувати порівняння рядків, що задовольнить потребам конкретного додатка. Отже, додавання параметра типу StringComparison розширює можливості методу Compare () та інших методів порівняння, наприклад, Equals (). Це дає також можливість однозначно вказувати спосіб запланованого порівняння рядків.

В силу відмінностей між порівнянням рядків з урахуванням культурного середовища та порядковим порівнянням дуже важливо бути максимально точним у цьому відношенні.

Значення в перерахуванні StringComparison

Значення

Опис

CurrentCulture

Порівняння рядків проводиться з поточними параметрами параметрів культурного середовища

CurrentCultureIgnoreCase

Порівняння рядків проводиться з поточними параметрами параметрів культурного середовища, але без урахування регістру

InvariantCulture

Порівняння рядків проводиться з використанням незмінних, тобто універсальних даних про культурне середовище

InvariantCultureIgnoreCase

Порівняння рядків проводиться з використанням незмінних, тобто універсальних даних про культурне середовище і без урахування регістру

Ordinal

Порівняння рядків проводиться з використанням порядкових значень символів в рядку. При цьому лексикографічний порядок може порушитися, а умовні позначення, прийняті в окремій культурному середовищі, ігноруються

OrdinalIgnoreCase

Порівняння рядків проводиться з використанням порядкових значень символів в рядку, але без урахування регістру

У будь-якому випадку метод Compare () повертає від'ємне значення, якщо перший порівнюваний рядок виявляється менше другого; позитивне значення, якщо перший порівнюваний рядок більше другого; і нарешті, нуль, якщо обидва порівнювані рядки рівні. Незважаючи на те що метод Compare () повертає нуль, якщо порівнювані рядки рівні, для визначення рівності символьних рядків, як правило, краще користуватися методом Equals () або ж оператором ==.

Справа в тому, що метод Compare () визначає рівність порівнюваних рядків на підставі порядку їх сортування. Так, якщо виконується порівняння рядків з урахуванням культурного середовища, то обидва рядки можуть виявитися однаковими по порядку їх сортування, але не рівними по суті. За замовчуванням рівність рядків визначається в методі Equals (), виходячи з порядкових значень символів і без урахування культурного середовища. Отже, за замовчуванням обидва рядки порівнюються в цьому методі на абсолютну, посимвольну рівність подібно до того, як це робиться в операторі ==.

Незважаючи на велику універсальність методу Compare (), для простого порядкового порівняння символьних рядків простіше користуватися методом CompareOrdinal (). І нарешті, слід мати на увазі, що метод CompareTo () виконує порівняння рядків тільки з урахуванням культурного середовища