13

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

4

6 回答 6

27

下面是 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
于 2020-01-31T19:43:56.047 回答
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()

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

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

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

于 2020-01-31T21:27:39.073 回答
4

我会选择这些实现:

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

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

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

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

于 2021-01-12T08:44:09.217 回答
1

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

蛇案例字符串

于 2020-05-10T08:40:03.373 回答
0

我在这里选择了一个答案,添加了标题案例并稍微更改了 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)
于 2021-07-19T22:29:56.600 回答
0

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

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()
}
于 2020-12-07T14:07:00.710 回答