如何将camel case字符串转换为snake case并返回惯用的Kotlin?

06odsfpq  于 2023-06-24  发布在  Kotlin
关注(0)|答案(7)|浏览(158)

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

35g0bw71

35g0bw711#

下面是String类的扩展,它使用正则表达式和替换来将字符串从camel case转换为snake case,以及从snake case转换为camel case:

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()
}

以下是使用String扩展名的示例:

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
3vpjnl9f

3vpjnl9f2#

这是我的尝试。

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()

我的方法也是以扩展函数的形式编写的,但它不使用正则表达式,而是逐个字符处理它们,并将处理结果折叠到累加器中,累加器的开头是一个空的StringBuilder。处理过程如下:

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

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

9avjhtql

9avjhtql3#

我会使用这些实现:

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

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

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

...它使用正则表达式来找到驼峰之前的位置,插入蛇,然后将整个字符串转换为小写。正则表达式由两部分组成,第一部分(?<=.)是一个正向后看,说明它前面必须有一个字符,第二部分(?=\\p{Upper})是一个正向前看,说明它后面必须有一个大写字符。

ui7jx7zq

ui7jx7zq4#

如果你的类路径中有jackson-databind,你可以使用下面的实用函数:

import com.fasterxml.jackson.databind.PropertyNamingStrategies

fun String.toSnakeCase(): String = 
    PropertyNamingStrategies.SnakeCaseStrategy().translate(this)

fun main() {
    // should output this_is_the_case
    println("thisIsTheCase".toSnakeCase())
}
jvlzgdj9

jvlzgdj95#

这是我对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")

这是你蛇串:这是 Camel 箱
变蛇为 Camel

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

6jygbczu

6jygbczu6#

我在这里采用了其中一个答案,添加了标题大小写,并对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)
0yycz8jy

0yycz8jy7#

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

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()
}

相关问题