Naik - s blog - замінити або стерти повторюваних символів в рядку

У даній статті буде розглянута замінити або стерти повторюваних символів в рядку за допомогою регулярних виразів Java.
Замінювати і видаляти повторювані символи буде через функції заміни класу String.
У класу String є чотири методи для заміни символів. Ось їх сигнатури:

  1. replace (char oldChar, char newChar): String
  2. replace (CharSequence target, CharSequence replacement): String
  3. replaceAll (String regex, String replacement): String
  4. replaceFirst (String regex, String replacement): String

Перші два методи в нашому випадку не знадобляться, тому що вони потрібні для заміни одного символу (char) на інший символ або послідовності символів (CharSequence) на іншу послідовність. CharSequence - це інтерфейс, який реалізують класи: String, StringBuilder і StringBuffer.
Зупинимося на двох останніх методах: replaceAll і replaceFirst. Обидва методи першим параметром приймають регулярний вираз (regex), а другим параметром текст заміни (replacement). replaceAll - замінює всі збіги, а replaceFirst замінює тільки перший збіг. У даній статті буде використовуватися тільки replaceAll.

  1. Уявімо собі таку задачу: потрібно видалити з рядка всі, хто стоїть поруч два однакових символу. Наприклад, з рядка «keeshh» повинна в підсумку вийти рядок «ks»

String text = "keeshh"; String result = text.replaceAll ( "([a-z]) \\ 1", ""); System.out.println (result); // "ks"

replaceAll - функція для заміни всіх збігів
[A-z] - вираз говорить про те, що на цьому місці повинен бути символ в діапазоні від a до z.
() - круглі дужки означають угруповання, послатися на яку можна за номером, причому нумерація починається з одиниці
\ 1 - вказує на те, що в цьому місці повинен бути такий же текст, як в угрупованні під номером 1. Зворотний слеш «\» необхідно екранувати, тому у виразі два слеша «\\»

  • Після видалення двох повторних символів, можуть знову утворитися повторні символи.
    Наприклад, якщо в рядку «keeshhs» замінити два поспіль повторюються символу, то вийде «kss», але подстроку «ss» також можна видалити. Помістимо описаний вище код в цикл, який буде повторюватися до тих пір, поки не будуть замінені всі повторні символи. У даній реалізації будемо намагатися видаляти повторення, поки змінюється (коротшає) довжина рядка

    String text = "keeshhs"; int len; dowhile (len! = text.length ()); // порівнюємо нову довжину рядка із збереженою довжиною System.out.println (text); // "k"

  • Розглянемо наступний приклад. Потрібно видалити всі повторювані поспіль символи.
    Наприклад, для рядка «keeeshh» результат повинен бути «ks». Реалізація:

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

  • Тепер розглянемо заміну. Завдання: є рядок, необхідно з двох поспіль однакових символів залишити тільки один.
    Приклад: з рядка «kkeesshh» вийде рядок «kesh».
    Реалізація:

    String text = "kkeesshh"; text = text.replaceAll ( "([a-z]) \\ 1", "$ 1"); System.out.println (text); // "kesh"

    Для заміни ми використовували вираз $ 1. яке говорить про те, що текст, відповідний регулярному виразу, необхідно замінити на текст, відповідний угрупованню з номером 1. У нашому випадку угруповання з номером - це текст, відповідний шаблоном [a-z].
    Можна переписати код, використовуючи групу з номером 2 для заміни:

    String text = "kkeesshh"; text = text.replaceAll ( "([a-z]) (\\ 1)", "$ 2"); System.out.println (text); // "kesh"

    Друга група відповідає шаблоном \\ 1

  • І наостанок замінимо в рядку все підряд повторювані символи одним символом.
    Наприклад, рядок «keeeeessshh» перетвориться в «kesh».
    Реалізація:

    String text = "keeeeessshh"; text = text.replaceAll ( "([a-z]) \\ 1+", "$ 1"); System.out.println (text); // "kesh"

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