Kotlin поиск всех подстрок

Использование регулярных выражений в Kotlin

Мы можем найти использование (или злоупотребление) регулярных выражений практически в любом программном обеспечении, от быстрых скриптов до невероятно сложных приложений. В этой статье мы увидим, как использовать регулярные выражения в Kotlin.

Мы не будем обсуждать синтаксис регулярных выражений; знакомство с регулярными выражениями в целом требуется для адекватного понимания статьи, и особенно рекомендуется знание синтаксиса шаблонов Java.

Настройка

Хотя регулярные выражения не являются частью языка Котлин, они поставляются с его стандартной библиотекой.

Вероятно, у нас уже есть это как зависимость нашего проекта:

 org.jetbrains.kotlin kotlin-stdlib 1.2.21 

Мы можем найти последнюю версию kotlin-stdlib на Maven Central.

Создание объекта регулярного выражения

Регулярные выражения — это экземпляры класса kotlin.text.Regex. Мы можем создать его несколькими способами.

Можно вызвать конструктор Regex:

или мы можем вызвать метод toRegex для строки:

Наконец, мы можем использовать статический фабричный метод:

За исключением различий, описанных в следующем разделе, эти параметры эквивалентны и зависят от личных предпочтений. Только не забывайте быть последовательными.

Совет: регулярные выражения часто содержат символы, которые интерпретируются как управляющие последовательности в строковых литералах. Таким образом, мы можем использовать необработанные строки, чтобы забыть о нескольких уровнях экранирования:

Параметры соответствия

И конструктор Regex, и метод toRegex позволяют нам указать одну дополнительную опцию или набор:

Regex("a(b|c)+d?", CANON_EQ) Regex("a(b|c)+d?", setOf(DOT_MATCHES_ALL, COMMENTS)) "a(b|c)+d?".toRegex(MULTILINE) "a(b|c)+d?".toRegex(setOf(IGNORE_CASE, COMMENTS, UNIX_LINES))

Параметры перечислены в классе RegexOption, который мы удобно импортировали статически в приведенном выше примере:

  • IGNORE_CASE — включает сопоставление без учета регистра.
  • MULTILINE – изменяет значение ^ и $.
  • LITERAL – приводит к тому, что метасимволы или escape-последовательности в шаблоне не имеют особого значения.
  • UNIX_LINES — в этом режиме только n распознается как признак конца строки.
  • COMMENTS — разрешает пробелы и комментарии в шаблоне.
  • DOT_MATCHES_ALL — заставляет точку соответствовать любому символу, включая разделитель строки.
  • CANON_EQ — включает эквивалентность посредством канонической декомпозиции.
Читайте также:  Ошибка инициализации криптопровайдера rsa java security providerexception initialization failed

Соответствие

Мы используем регулярные выражения в первую очередь для сопоставления входных строк, а иногда и для извлечения или замены их частей.

Теперь мы подробно рассмотрим методы, предлагаемые классом Kotlin Regex для сопоставления строк.

Проверка частичных или полных совпадений

В этих случаях использования нам интересно знать, удовлетворяет ли String или часть String нашему регулярному выражению.

Если нам нужно только частичное совпадение, мы можем использовать containsMatchIn:

val regex = """a([bc]+)d?""".toRegex() assertTrue(regex.containsMatchIn("xabcdy"))

Если мы хотим, чтобы вместо этого совпадала вся строка, мы используем match:

assertTrue(regex.matches("abcd"))

Обратите внимание, что мы также можем использовать совпадения в качестве инфиксного оператора:

assertFalse(regex matches "xabcdy")

Извлечение совпадающих компонентов

В этих случаях использования мы хотим сопоставить строку с регулярным выражением и извлечь части строки.

Мы можем захотеть сопоставить всю строку:

val matchResult = regex.matchEntire("abbccbbd")

Или мы можем захотеть найти первую совпадающую подстроку:

val matchResult = regex.find("abcbabbd")

Или, может быть, найти все совпадающие подстроки сразу, как Set:

val matchResults = regex.findAll("abcb abbd")

В любом случае, если сопоставление прошло успешно, результатом будет один или несколько экземпляров класса MatchResult. В следующем разделе мы увидим, как его использовать.

Вместо этого, если совпадение не удалось, эти методы возвращают null или пустой Set в случае findAll.

Класс MatchResult

Экземпляры класса MatchResult представляют собой успешные совпадения некоторой входной строки с регулярным выражением; полное или частичное совпадение (см. предыдущий раздел).

Таким образом, они имеют значение, которое является совпадающей строкой или подстрокой:

val regex = """a([bc]+)d?""".toRegex() val matchResult = regex.find("abcb abbd") assertEquals("abcb", matchResult.value)

И у них есть ряд индексов, чтобы указать, какая часть ввода была сопоставлена:

assertEquals(IntRange(0, 3), matchResult.range)

Группы и деструктуризация

Мы также можем извлекать группы (сопоставленные подстроки) из экземпляров MatchResult.

Мы можем получить их как строки:

assertEquals(listOf("abcb", "bcb"), matchResult.groupValues)

Или мы также можем рассматривать их как объекты MatchGroup, состоящие из значения и диапазона:

assertEquals(IntRange(1, 3), matchResult.groups[1].range)

Группа с индексом 0 всегда представляет собой всю совпадающую строку. Вместо этого индексы больше 0 представляют группы в регулярном выражении, разделенные круглыми скобками, например ([bc]+) в нашем примере.

Читайте также:  Массивы в питоне типы

Мы также можем деструктурировать экземпляры MatchResult в операторе присваивания:

val regex = """([ws]+) is(d+) years old""".toRegex() val matchResult = regex.find("Mickey Mouse is 95 years old") val(name, age) = matchResult. destructured assertEquals("Mickey Mouse", name) assertEquals("95", age)

Несколько совпадений

MatchResult также имеет следующий метод, который мы можем использовать для получения следующего совпадения входной строки с регулярным выражением, если оно есть:

val regex = """a([bc]+)d?""".toRegex() var matchResult = regex.find("abcb abbd") assertEquals("abcb", matchResult. value) matchResult = matchResult.next() assertEquals("abbd", matchResult. value) matchResult = matchResult.next() assertNull(matchResult)

Как мы видим, next возвращает null, когда совпадений больше нет.

Замена

Еще одно распространенное использование регулярных выражений — замена совпадающих подстрок другими строками. Для этой цели у нас есть два метода, доступных в стандартной библиотеке.

Один из них replace предназначен для замены всех вхождений совпадающей строки:

val regex = """(red|green|blue)""".toRegex() val beautiful = "Roses are red, Violets are blue" val grim = regex.replace(beautiful, "dark") assertEquals("Roses are dark, Violets are dark", grim)

Другой, replaceFirst, предназначен для замены только первого вхождения:

val shiny = regex.replaceFirst(beautiful, "rainbow") assertEquals("Roses are rainbow, Violets are blue", shiny)

Сложные замены

Для более сложных сценариев, когда мы не хотим заменять совпадения постоянными строками, а вместо этого хотим применить преобразование, Regex по-прежнему дает нам то, что нам нужно.

Введите перегрузку замены, принимая закрытие:

val reallyBeautiful = regex.replace(beautiful) < m ->m.value.toUpperCase() + "!" > assertEquals("Roses are RED!, Violets are BLUE!", reallyBeautiful)

Как мы видим, для каждого совпадения мы можем вычислить замену String, используя это совпадение.

Разделение

Наконец, мы можем захотеть разбить строку на список подстрок в соответствии с регулярным выражением. Опять же, регулярное выражение Kotlin помогло нам:

val regex = """W+""".toRegex() val beautiful = "Roses are red, Violets are blue" assertEquals(listOf( "Roses", "are", "red", "Violets", "are", "blue"), regex.split(beautiful))

Здесь регулярное выражение соответствует одному или нескольким символам, не являющимся словами, поэтому результатом операции разделения является список слов.

Мы также можем установить ограничение на длину результирующего списка:

assertEquals(listOf("Roses", "are", "red", "Violets are blue"), regex.split(beautiful, 4))

Совместимость с Java

Если нам нужно передать наше регулярное выражение в код Java или какой-либо другой API языка JVM, который ожидает экземпляр java.util.regex.Pattern, мы можем просто преобразовать наше регулярное выражение:

Читайте также:  Add directory to file java

В этой статье мы рассмотрели поддержку регулярных выражений в стандартной библиотеке Kotlin.

Средняя оценка 0 / 5. Количество голосов: 0

Спасибо, помогите другим — напишите комментарий, добавьте информации к статье.

Видим, что вы не нашли ответ на свой вопрос.

Напишите комментарий, что можно добавить к статье, какой информации не хватает.

Источник

Найти все вхождения символа в строку Kotlin

В этой статье рассматриваются различные способы поиска индексов всех вхождений символа или подстроки в строку Kotlin.

1. Найти все индексы персонажа

The indexOf() Функция возвращает только индекс “первого” появления символа в строке, как показано ниже:

Точно так же lastIndexOf() Функция возвращает индекс “последнего” появления символа в строке.

Чтобы найти индекс всех экземпляров символа в строке, эффективно вызовите метод indexOf() повторяться в цикле. Обратите внимание, что поиск следующего индекса начинается с предыдущего индекса.

результат:

3
8
15
21

результат:

3
8
15
21

2. Найти все индексы подстроки

Мы можем использовать RegEx, чтобы найти индексы всех вхождений “подстроки” в String. Типичная реализация этого подхода будет выглядеть так:

Чтобы включить поиск без учета регистра, укажите IGNORE_CASE вариант регулярного выражения.

Мы можем обрабатывать некоторые специальные входные данные, такие как перекрывающиеся символы, изменив регулярное выражение для использования положительного просмотра вперед. Например,

Это все о поиске индексов всех вхождений символа или подстроки в строку Kotlin.

Средний рейтинг 4.69 /5. Подсчет голосов: 13

Голосов пока нет! Будьте первым, кто оценит этот пост.

Сожалеем, что этот пост не оказался для вас полезным!

Расскажите, как мы можем улучшить этот пост?

Спасибо за чтение.

Пожалуйста, используйте наш онлайн-компилятор размещать код в комментариях, используя C, C++, Java, Python, JavaScript, C#, PHP и многие другие популярные языки программирования.

Как мы? Порекомендуйте нас своим друзьям и помогите нам расти. Удачного кодирования 🙂

Этот веб-сайт использует файлы cookie. Используя этот сайт, вы соглашаетесь с использованием файлов cookie, нашей политикой, условиями авторского права и другими условиями. Читайте наши Политика конфиденциальности. Понятно

Источник

Оцените статью