Просмотр вперед и назад в Kotlin
Иногда нужно решить задачу такого типа:
найти строку 'aaa' и заменить ее
на '!', но только если после
'aaa' стоит 'x', а сам
'x' при этом не заменять. Если мы
попытаемся решить задачу 'в лоб',
то у нас ничего не выйдет:
val txt = "aaax baaa"
val res = Regex("aaax").replace(txt, "!")
println(res) # выведет '! baaa', а хотели '!x baaa'
Просмотр вперед
Для решения задачи нужен способ сказать,
что 'x' не следует заменять. Делается
это .
Эти скобки называются позитивный просмотр
вперед. Позитивный - так как 'x'
(в нашем случае) должен быть - только тогда
произойдет замена.
Применим эти скобки для решения нашей задачи:
val txt = "aaax baaa"
val res = Regex("aaa(?=x)").replace(txt, "!")
println(res) # выведет '!x aaab
Есть и негативный просмотр вперед
- (?! ) - он, наоборот, говорит,
что чего-то должно не быть. В следующем
примере, замена произойдет, только если
после 'aaa' стоит НЕ 'x':
val txt = "aaax aaab"
val res = Regex("aaa(?!x)").replace(txt, "!")
println(res) # выведет 'aaax !b'
Просмотр назад
Аналогичным образом есть позитивный
просмотр назад - (?<= ). В
следующем примере замена произойдет, только
если перед 'aaa' стоит 'x':
val txt = "xaaa"
val res = Regex("(?<=x)aaa").replace(txt, "!")
println(res) # выведет 'x!'
И есть также негативный просмотр назад
- (?<! ). В следующем примере
замена произойдет, только если перед
'aaa' не стоит 'x':
val txt = "baaa"
val res = Regex("(?<!x)aaa").replace(txt, "!")
println(res) # выведет 'b!'
Практические задачи
Дана строка, содержащая имена функций:
val txt = "func1() func2() func3()"
Получите массив имен функций из строки.
Дана строка с тегом:
val txt = "<a href=\"\" class=\"eee\" id=\"zzz\">"
Получите массив имен атрибутов этого тега.
Дана строка с переменными:
val txt = "$aaa $bbb $ccc xxxx"
Получите подстроки, перед которыми стоит символ доллара.