All Downloads are FREE. Search and download functionalities are using the official Maven repository.

main.com.xml.guard.utils.StringUtil.kt Maven / Gradle / Ivy

package com.xml.guard.utils

import org.gradle.api.Project
import java.io.File
import kotlin.math.pow
import kotlin.random.Random

/**
 * User: ljx
 * Date: 2022/3/1
 * Time: 17:31
 */

// 从前缀列表中,获取最符合的前缀
fun String.findBestPrefix(prefixes: List): String {
    return kotlin.runCatching {
        prefixes.maxBy { prefix ->
            (if (this.startsWith(prefix)) prefix else "").length
        }
    }.getOrNull() ?: this
}

fun String.replaceLast(oldValue: String, newValue: String): String {
    val index = lastIndexOf(oldValue)
    return if (index == -1) this else substring(0, index) + newValue
}

// 移除后缀
fun String.removeSuffix(): String {
    val index = lastIndexOf(".")
    return if (index == -1) this else substring(0, index)
}

// 获取后缀
fun String.getSuffix(): String {
    val index = lastIndexOf(".")
    return if (index == -1) "" else substring(index)
}

fun String.getDirPath(): String {
    val index = lastIndexOf(".")
    return if (index == -1) this else substring(0, index)
}

// 获取类文件包名
fun getClassPackage(project: Project, file: File): String {
    val srcMainPath = project.file("src${File.separator}main").absolutePath + File.separator
    val filePath = file.absolutePath
    var rawPackage = filePath.replace(srcMainPath, "")
        .replaceBefore(File.separator, "")
        .replaceAfterLast(File.separator, "")

    var startIndex = rawPackage.indexOf(File.separator)
    startIndex = if (startIndex != -1) startIndex + 1 else 0

    var endIndex = rawPackage.lastIndexOf(File.separator)
    endIndex = if (endIndex != -1) endIndex else rawPackage.length

    rawPackage = rawPackage.substring(startIndex, endIndex)
        .replace(File.separator, ".")
    return rawPackage
}

// 文件名转为驼峰形式
fun String.convertToCamelCase(): String {
    // 假设文件名可能包含下划线、连字符、点或空格作为分隔符
    val words = this.split("_", "-", ".", " ")
    val camelCaseBuilder = StringBuilder()
    for (word in words) {
        if (word.isNotBlank()) {
            // 将单词的首字母大写并追加到结果中
            camelCaseBuilder.append(word.uppercaseFirstChar())
        }
    }
    return camelCaseBuilder.toString()
}

// 首字母小写
fun String.lowercaseFirstChar(): String {
    return this.replaceFirstChar { it.lowercase() }
}

// 首字母大写
fun String.uppercaseFirstChar(): String {
    return this.replaceFirstChar { if (it.isLowerCase()) it.titlecase() else it.toString() }
}

// 获取 layout 布局所对应的 Binding 名称
fun String.getLayoutBindingName(): String {
    return this.convertToCamelCase() + "Binding"
}

fun String.findWord(
    word: String,
    ignoreCase: Boolean = false
): Int {
    var occurrenceIndex = indexOf(word, 0, ignoreCase)
    // FAST PATH: no match
    if (occurrenceIndex < 0) return -1

    val oldValueLength = word.length
    val searchStep = oldValueLength.coerceAtLeast(1)

    do {
        if (isWord(occurrenceIndex, word)) {
            return occurrenceIndex
        }
        if (occurrenceIndex >= length) break
        occurrenceIndex = indexOf(word, occurrenceIndex + searchStep, ignoreCase)
    } while (occurrenceIndex > 0)
    return -1
}

fun String.replaceWordsByPattern(oldValue: String, newValue: String): String {
    // \b 表示单词边界
    val matcher = "\\b${oldValue}\\b".toPattern().matcher(this)
    return matcher.replaceAll(newValue)
}

fun String.replaceWords(
    oldValue: String,
    newValue: String,
    ignoreCase: Boolean = false
): String {
    var occurrenceIndex = indexOf(oldValue, 0, ignoreCase)
    // FAST PATH: no match
    if (occurrenceIndex < 0) return this

    val oldValueLength = oldValue.length
    val searchStep = oldValueLength.coerceAtLeast(1)
    val newLengthHint = length - oldValueLength + newValue.length
    if (newLengthHint < 0) throw OutOfMemoryError()
    val stringBuilder = StringBuilder(newLengthHint)

    var i = 0
    do {
        if (isWord(occurrenceIndex, oldValue)) {
            stringBuilder.append(this, i, occurrenceIndex).append(newValue)
        } else {
            stringBuilder.append(this, i, occurrenceIndex + oldValueLength)
        }
        i = occurrenceIndex + oldValueLength
        if (occurrenceIndex >= length) break
        occurrenceIndex = indexOf(oldValue, occurrenceIndex + searchStep, ignoreCase)
    } while (occurrenceIndex > 0)
    return stringBuilder.append(this, i, length).toString()
}

fun String.isWord(index: Int, oldValue: String): Boolean {
    val firstChar = oldValue[0].code
    if (index > 0 && (firstChar in 65..90 || firstChar == 95 || firstChar in 97..122)) {
        val prefix = get(index - 1).code
        // $ . 0-9 A-Z _ a-z
        if (prefix == 36 || prefix == 46 || prefix in 48..57 || prefix in 65..90 || prefix == 95 || prefix in 97..122) {
            return false
        }
    }
    val endChar = oldValue[oldValue.lastIndex].code
    // $ 0-9 A-Z _ a-z
    if (endChar == 36 || endChar in 48..57 || endChar in 65..90 || endChar == 95 || endChar in 97..122) {

        val suffix = getOrNull(index + oldValue.length)?.code
        // $ 0-9 A-Z _ a-z
        if (suffix == 36 || suffix in 48..57 || suffix in 65..90 || suffix == 95 || suffix in 97..122) {
            return false
        }
    }
    return true
}

// 字符串随机转换大小写
fun String.randomizeCase(): String {
    return this.map {
        if (Random.nextBoolean()) {
            it.uppercaseChar()
        } else {
            it.lowercaseChar()
        }
    }.joinToString("")
}

// Long 转 大写字符串
fun Long.toUpperLetterStr(): String {
    return toLetterStr(true)
}

// Long 转 大/小字符串
fun Long.toLetterStr(upperCase: Boolean = false): String {
    val size = 26
    val offSize = if (upperCase) 65 else 97
    val sb = StringBuilder()
    var num = this
    do {
        val char = (num % size + offSize).toInt().toChar()
        sb.append(char)
        num /= size
    } while (num > 0)
    return sb.reverse().toString()
}

// 字符串转Long
fun String.to26Long(): Long {
    val length = length
    var num = 0L
    for (i in 0 until length) {
        val c = get(i)
        val offSize = if (c.isUpperCase()) 65 else 97
        num += ((c.code - offSize) * 26.0.pow((length - 1 - i).toDouble())).toLong()
    }
    return num
}

internal fun String.splitWords(): List {
    val regex = Regex("(?<=[a-z])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])")
    return split(regex).map { it.lowercase() }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy