String 去除kotlin中的重音和变音符号
在kotlin中,有没有办法将类似“Dzikuję”的字符串转换为“Dziekuje”或“šećer”转换为“secer”呢。我尝试过使用java.text.Normalizer,但似乎没有达到预期效果。这是一个可以使用并进一步扩展的扩展函数:String 去除kotlin中的重音和变音符号,string,kotlin,String,Kotlin,在kotlin中,有没有办法将类似“Dzikuję”的字符串转换为“Dziekuje”或“šećer”转换为“secer”呢。我尝试过使用java.text.Normalizer,但似乎没有达到预期效果。这是一个可以使用并进一步扩展的扩展函数: fun String.normalize(): String { val original = arrayOf("ę", "š") val normalized = arrayOf("e", "s") return this.
fun String.normalize(): String {
val original = arrayOf("ę", "š")
val normalized = arrayOf("e", "s")
return this.map { it ->
val index = original.indexOf(it.toString())
if (index >= 0) normalized[index] else it
}.joinToString("")
}
像这样使用:val originalText = "aębšc"
val normalizedText = originalText.normalize()
println(normalizedText)
将打印aebsc
使用所需的元素扩展数组
原始
和规范化
Normalizer只完成一半的工作。以下是您可以如何使用它:
private val REGEX_UNACCENT = "\\p{InCombiningDiacriticalMarks}+".toRegex()
fun CharSequence.unaccent(): String {
val temp = Normalizer.normalize(this, Normalizer.Form.NFD)
return REGEX_UNACCENT.replace(temp, "")
}
assert("áéíóů".unaccent() == "aeiou")
下面是它的工作原理:
我们正在调用normalize()。如果我们通过a,该方法将返回a+`。然后使用正则表达式清理字符串,只保留有效的US-ASCII字符
资料来源:
请注意,
Normalizer
是一个Java类;这不是纯粹的Kotlin,它只在JVM上工作。如果有人在Kotlin中挣扎着这样做,这段代码就像一个符咒。
为了避免不一致,我还使用.toUpperCase和Trim()。然后我抛出这个函数:
fun stripAccents(s: String):String{
if (s == null) {
return "";
}
val chars: CharArray = s.toCharArray()
var sb = StringBuilder(s)
var cont: Int = 0
while (chars.size > cont) {
var c: kotlin.Char
c = chars[cont]
var c2:String = c.toString()
//these are my needs, in case you need to convert other accents just Add new entries aqui
c2 = c2.replace("Ã", "A")
c2 = c2.replace("Õ", "O")
c2 = c2.replace("Ç", "C")
c2 = c2.replace("Á", "A")
c2 = c2.replace("Ó", "O")
c2 = c2.replace("Ê", "E")
c2 = c2.replace("É", "E")
c2 = c2.replace("Ú", "U")
c = c2.single()
sb.setCharAt(cont, c)
cont++
}
return sb.toString()
}
要使用这些有趣的方法,请按如下方式转换代码:
var str: String
str = editText.text.toString() //get the text from EditText
str = str.toUpperCase().trim()
str = stripAccents(str) //call the function
TL;医生:
Normalizer
对Unicode文本进行规范化分解\p{Mn}
)长答案: 使用可以将原始文本转换为等效的合成或分解形式
- NFD:正则分解
- NFC:标准分解,然后是标准合成
(有关规范化的更多信息,请参阅) 在我们的例子中,我们对NFD规范化形式感兴趣,因为它允许我们将所有组合字符从基本字符中分离出来 分解文本后,我们必须运行一个正则表达式来删除分解后产生的与组合字符对应的所有新字符 组合字符是相对于相关基本字符定位的特殊字符。Unicode标准区分两种类型的组合字符:空格和非空格 我们只对无间距组合字符感兴趣。变音符号是这一组中的主要类别(但不是唯一一个),与拉丁语、希腊语和西里尔语及其亲属一起使用 要使用正则表达式删除非间隔字符,我们必须使用
\p{Mn}
。这一组包括
其他答案使用
\p{InCombiningDiacriticalMarks}
,此块仅包括组合变音标记。它是\p{Mn}
的子集,仅包括。“但它似乎没有按预期的方式工作。”如何?出了什么事?对不起。我忘了将正则表达式转换为正则表达式。基本上,我的意思是,我缺乏使用normalizer的经验,因此几乎不知道我在说什么。谢谢。这正是我想要的。谢谢你的回答。这是一个很好的解决整个规范化程序问题的方法。我最终使用了这个解决方案,因为规范化程序对Ø字符没有影响,我想将其转换为O。
fun String.removeNonSpacingMarks() =
Normalizer.normalize(this, Normalizer.Form.NFD)
.replace("\\p{Mn}+".toRegex(), "")