All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
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
*/
private const val LETTERS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
private const val LETTERS_AND_NUMBERS = LETTERS + "0123456789"
/**
* 判断字符是否为小写,排除掉数字
*/
fun String?.isLowercase(): Boolean {
return this?.filter { !it.isDigit() }?.all { it.isLowerCase() } ?: false
}
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 String.getClassName(): String {
val index = lastIndexOf(".")
return if (index == -1) this else substring(index + 1)
}
// 获取类文件包名
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.trim()
}
// 文件名转为驼峰形式
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("")
}
/**
* 获取随机字符,该字符长度均匀分布在指定的 [from](含)和 [until](不包括)边界之间。
*
* @param filter 用于字符过滤处理;若返回为空则重新生成字符
*/
fun getRandomString(
from: Int = 2,
until: Int = 7,
onlyLetter: Boolean = false,
filter: (text: String) -> String?
): String {
val length = Random.nextInt(from, until)
val builder = StringBuilder()
while (true) {
if (builder.isNotBlank()) {
builder.clear()
}
// 确保首字符为字母
builder.append(LETTERS.random())
// 生成剩余字符
val source = if (onlyLetter) LETTERS else LETTERS_AND_NUMBERS
for (i in 1 until length) {
builder.append(source.random())
}
val text = builder.toString()
val result = filter.invoke(text)
if (result?.isNotBlank() == true && !result.inBlackList()) {
return result
}
}
}
// 是否在黑名单
fun String.inBlackList(): Boolean {
return this.inPackageNameBlackList() || this.inClassNameBlackList()
}
// 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
@Suppress("CheckResult")
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() }
}