Search code examples
regexkotlinstringbuilder

How to change different substrings in a string?


I have a file with a certain number of lines. I need to find all double letters and change the second letter to the one that corresponds to it in the map.
Case of replaced letters should be kept.
Example:
"kotlIn is a functional programming Language"
should become
"kotlYn is a functionol programmyng Longuage"

fun changeChar(inputFileName: String, outputFileName: String) {
    val outputStream = File(outputFileName).bufferedWriter()
    val charsRegex = "([klmn][aei])".toRegex(setOf(RegexOption.IGNORE_CASE))
    val validChars = mapOf('a' to 'o', 'e' to 'u', 'i' to 'y')
    File(inputFileName).forEachLine { line ->
        val sb = StringBuilder(line).replace(charsRegex, /*here is my difficulty*/)
        outputStream.write(sb)
        outputStream.newLine()
    }
    outputStream.close()
}

I spent many hours, but could not find solutions on the Internet and the standard Kotlin library.


Solution

  • Another idiomatic solution would be to transform the matched string using the replace(...) { ... } overload that accepts a lambda to handle each MatchResult:

    val charsRegex = "[klmn][aei]".toRegex(RegexOption.IGNORE_CASE)
    val validChars = mapOf('a' to 'o', 'e' to 'u', 'i' to 'y')
    
    val result = line.replace(charsRegex) {
        val vowel = it.value[1]
        val validLetter = validChars.getValue(vowel.toLowerCase())
        val validCaseLetter = if (vowel.isLowerCase()) validLetter else validLetter.toUpperCase()
        it.value.take(1) + validCaseLetter
    }
    

    (runnable sample)