如何更改字符串中的不同子字符串?

时间:2019-01-30 16:07:16

标签: regex kotlin stringbuilder

我有一个带有特定行数的文件。 我需要找到所有的双字母并将第二个字母更改为对应于地图中的字母。
保留替换字母的情况。
例如:
{"kotlIn is a functional programming Language"
应该成为
"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()
}

我花了很多时间,但是无法在Internet和标准Kotlin库中找到解决方案。

4 个答案:

答案 0 :(得分:1)

没有任何正则表达式:

worker_processes 1;
events {
  worker_connections 1024;
}

http {
  server {
    listen 80;
    client_max_body_size 100G;
    aws_access_key "AKIAxxxx";
    aws_signing_key "489OW0/xxxx=";
    aws_key_scope "20190130/eu-west-1/s3/aws4_request";
    aws_s3_bucket "bucket_name";
    location / {
      aws_sign;
      proxy_set_header x-amz-cf-id "";
      proxy_pass http://bucket_name.s3.amazonaws.com;
      proxy_set_header Host "bucket_name.s3-eu-west-1.amazonaws.com";
      set_by_lua $now "return ngx.cookie_time(ngx.time())";
      proxy_set_header x-amz-date $now;
      proxy_hide_header "x-amz-id-2";
      proxy_hide_header "x-amz-request-id";
      resolver 8.8.8.8 valid=300s;
      resolver_timeout 10s;
    }
}
}

将打印:

  

kotlYn是myong Longuage的功能程序

答案 1 :(得分:1)

尝试一下。

fun main(args: Array<String>) {
    val str = "kotlIn is a functional programming Language"
    val validChars = mapOf("a" to "o", "e" to "u", "i" to "y" )
    val charsRegex = "(?=(.))([klmn][aei])(?<=(.))".toRegex(setOf(RegexOption.IGNORE_CASE))
    val found = charsRegex.findAll(str)
    var newStr= str
    found.forEach { f ->
        val m = f.value.toLowerCase()
        val idx = f.range
        val k = m.substring(1)
        val repStr = m.substring(0,1) + validChars.get(k)?.toUpperCase()
        newStr= newStr.replaceRange(idx,repStr)
       // println("$m found at indexes: $idx  ${validChars.get(k)} ${newStr}" )
     }
    println( "NewStr = ${newStr}")
}

打印

NewStr = kotlYn is a functionOl programmYng lOnguage

PS:我在Kotlin方面并不擅长,但是我认为您可以对其进行一些调整以获得准确的结果。

答案 2 :(得分:1)

另一种惯用的解决方案是使用replace(...) { ... }重载来转换匹配的字符串,该重载接受一个lambda来处理每个MatchResult

income_gap_chart <- ggplot(income_gap, aes(x = Country, y = Percent, fill = Income)) + 
geom_bar(position = "dodge", stat = "identity") +
scale_fill_brewer(palette = "Set1") +
coord_flip() +
theme(axis.title.y = element_blank()) +
scale_y_continuous(limits = c(0, 100)) +
theme_tufte() +
theme(axis.title.y = element_blank()) +
theme(legend.position = "bottom")

(runnable sample)

答案 3 :(得分:1)

我将使用replace,它也将转换lambda作为建议的热键。但是我将正则表达式更改为具有两个组。

  • 第一组后面是一个积极的表情,这意味着它将被匹配但不会被捕获,因为不必替换第一个字母
  • 第二组将被捕获,因为第二个字母必须用另一个字符替换

代码:

fun replaceInvalidPairs(line: String): String {
    val charsRegex = "(?<=[klmn])([aei])".toRegex(setOf(RegexOption.IGNORE_CASE))
    val validChars = mapOf('a' to 'o', 'e' to 'u', 'i' to 'y')

    return charsRegex.replace(line) {
        val secondLetter = it.groupValues.first().first()
        val replacement = validChars[secondLetter.toLowerCase()]!!
        (if (secondLetter.isUpperCase()) replacement.toUpperCase() else replacement).toString()
    }
}

结果:

  

kotlYn是myong Longuage的功能程序