如何在惯用的 Kotlin 中将驼峰式字符串转换为蛇形字符串并返回?

TER*_*TER 12 string kotlin snakecasing

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

TER*_*TER 22

以下是 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()
}

Run Code Online (Sandbox Code Playgroud)

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

print("${"MyCamelCaseA".camelToSnakeCase()}\n")
my_camel_case_a
Run Code Online (Sandbox Code Playgroud)
print("${"AMultiWordString".camelToSnakeCase()}\n")
a_multi_word_string
Run Code Online (Sandbox Code Playgroud)
"my_camel_case_a".snakeToLowerCamelCase()
myCamelCaseA
Run Code Online (Sandbox Code Playgroud)
"my_camel_case_a".snakeToUpperCamelCase()
MyCamelCaseA
Run Code Online (Sandbox Code Playgroud)

  • 可以通过以下方式稍微缩短: `regex.replace(this)` -&gt; `replace(regex)` (2认同)

Per*_*uss 12

我会采用这些实现:

fun String.toCamelCase() = 
    split('_').joinToString("", transform = String::capitalize)
Run Code Online (Sandbox Code Playgroud)

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

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

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


ysa*_*hno 6

这是我的尝试。

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()
Run Code Online (Sandbox Code Playgroud)

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

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

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