【问题标题】:How can I convert a camel case string to snake case and back in idiomatic Kotlin?如何在惯用的 Kotlin 中将驼峰字符串转换为蛇形字符串并返回?
【发布时间】:2020-01-31 19:43:56
【问题描述】:

寻找可以进行如下转换的代码: “MyCamelCaseA”到“my_camel_case_a” “AMultiWordString”到“a_multi_word_string” “my_camel_case_a”到“myCamelCaseA”或“MyCamelCaseA” "a_multi_word_string" 到 "aMultiWordString" 或 "AMultiWordString"

【问题讨论】:

    标签: string kotlin snakecasing


    【解决方案1】:

    以下是 String 类的扩展,它们使用正则表达式和替换将字符串从驼峰式转换为蛇形,从蛇形转换为驼峰:

    val camelRegex = "(?<=[a-zA-Z])[A-Z]".toRegex()
    val snakeRegex = "_[a-zA-Z]".toRegex()
    
    // String extensions
    fun String.camelToSnakeCase(): String {
        return camelRegex.replace(this) {
            "_${it.value}"
        }.toLowerCase()
    }
    
    fun String.snakeToLowerCamelCase(): String {
        return snakeRegex.replace(this) {
            it.value.replace("_","")
                .toUpperCase()
        }
    }
    
    fun String.snakeToUpperCamelCase(): String {
        return this.snakeToLowerCamelCase().capitalize()
    }
    
    

    以下是使用字符串扩展的示例:

    print("${"MyCamelCaseA".camelToSnakeCase()}\n")
    my_camel_case_a
    
    print("${"AMultiWordString".camelToSnakeCase()}\n")
    a_multi_word_string
    
    "my_camel_case_a".snakeToLowerCamelCase()
    myCamelCaseA
    
    "my_camel_case_a".snakeToUpperCamelCase()
    MyCamelCaseA
    

    【讨论】:

    • 可以稍微缩短:regex.replace(this) -> replace(regex)
    【解决方案2】:

    这是我的尝试。

    fun String.camelToSnakeCase() = fold(StringBuilder(length)) { acc, c ->
        if (c in 'A'..'Z') (if (acc.isNotEmpty()) acc.append('_') else acc).append(c + ('a' - 'A'))
        else acc.append(c)
    }.toString()
    

    我的做法也是用扩展函数的形式写的,但是它没有使用正则表达式,而是逐个字符地处理,将处理结果折叠到累加器中,累加器开头是一个空的@ 987654322@。处理如下:

    • 如果字符不是大写拉丁字母,则按原样将其添加到累加器中
    • 如果字符一个大写拉丁字母,那么还要检查这是否不是字符串的第一个字符(累加器不为空)。如果不是,则在累加器中添加下划线。最后添加小写字符。

    需要注意的是,使用的是kotlin.text.StringBuilder,而不是JDK。

    【讨论】:

      【解决方案3】:

      我会选择这些实现:

      fun String.toCamelCase() = 
          split('_').joinToString("", transform = String::capitalize)
      

      ...它使用蛇作为分隔符分割字符串,然后将部分重新附加为不带分隔符的大写单词。

      fun String.toSnakeCase() = replace(humps, "_").toLowerCase()
      private val humps = "(?<=.)(?=\\p{Upper})".toRegex()
      

      ... 它使用正则表达式查找驼峰前的位置,插入蛇,然后将整个字符串转换为小写。正则表达式由两部分组成,第一个 (?&lt;=.) 是肯定的后视表示它必须前面有一个字符,第二部分 (?=\\p{Upper}) 是使用一个肯定的前向表示它必须后跟一个字符大写字符。

      【讨论】:

        【解决方案4】:

        这只是我对 kotlin 的尝试

           val  camelCaseString = "thisIsCamelCase"
            val snakeCaseString = camelCaseString.map {
                if (it.isUpperCase()){
                    "_${it.toLowerCase()}"
                }else
        {"$it"}
            }
        .joinToString(separator = "")
        System.out.println("here is your snake string: $snake_case_string")
        

        这是你的蛇串:this_is_camel_case

        从蛇变成骆驼

        val snakeCaseString = "snake_case_string"
        val camelCase = StringBuilder()
        var prevChar = '$'
        snakeCaseString.forEach {
        if(prevChar.equals('_')){
            camelCase.append(it.toUpperCase())
        }else if(!it.equals('_')){
            camelCase.append(it)
        }
            prevChar = it
        }
        
        System.out.println(camelCase.toString())
        

        snakeCaseString

        【讨论】:

          【解决方案5】:

          如果你想要一个有输入和输出的方法,我就是这样做的:

          private fun convertCamelToSnakeCase(camelCase : String) : String {
              val snakeCase = StringBuilder()
              for(character in camelCase) {
                  if(character.isUpperCase()) {
                      snakeCase.append("_${character.toLowerCase()}")
                  } else {
                      snakeCase.append(character)
                  }
              }
              return snakeCase.removePrefix("_").toString()
          }
          

          【讨论】:

            【解决方案6】:

            我在这里选择了一个答案,添加了 Title Case 并稍微更改了 API

            val camelRegex = "(?<=[a-zA-Z])[A-Z]".toRegex()
            val snakeRegex = "_[a-zA-Z]".toRegex()
            
            @JvmInline
            value class SnakeCaseString(private val string: String) {
                fun toCamelCase(): String = snakeRegex.replace(string) { it.value.replace("_", "").uppercase() }
                fun toUpperCamelCase(): String =
                    toCamelCase().replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
                fun toTitleCase(): String = snakeRegex.replace(string) { it.value.replace("_", " ").uppercase() }
                    .replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
            }
            
            @JvmInline
            value class CamelCaseString(private val string: String) {
                fun toSnakeCase(): String = camelRegex.replace(string) { "_${it.value}" }.lowercase()
                fun toTitleCase(): String = camelRegex.replace(string) { "_${it.value}" }
                    .replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
            }
            
            fun String.asSnakeCase() = SnakeCaseString(this)
            fun String.asCamelCase() = CamelCaseString(this)
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2023-02-20
              • 1970-01-01
              • 2019-10-30
              • 2011-02-27
              • 2018-05-29
              相关资源
              最近更新 更多