删除Kotlin中的重音符号和变音符号

时间:2018-08-07 16:34:57

标签: string kotlin

在科特林中,有没有办法将'Dziękuję'等字符串转换为'Dziekuje'或将'šećer'转换为'secer'。我尝试使用java.text.Normalizer,但似乎无法按预期方式工作。

4 个答案:

答案 0 :(得分:5)

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 +`。然后,使用正则表达式清理字符串以仅保留有效的US-ASCII字符。

来源:http://www.rgagnon.com/javadetails/java-0456.html

请注意Normalizer是Java类;这不是纯Kotlin,只能在JVM上使用。

答案 1 :(得分:2)

这是一个扩展功能,可以使用并进一步扩展:

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

根据需要扩展具有所有元素的数组originalnormalized

答案 2 :(得分:2)

TL; DR:

  1. 使用Normalizer规范地分解Unicode thext。
  2. 删除非空格组合字符(\p{Mn})。

fun String.removeNonSpacingMarks() =
    Normalizer.normalize(this, Normalizer.Form.NFD)
    .replace("\\p{Mn}+".toRegex(), "")

长答案:

使用Normalizer,您可以将原始文本转换为等效的组合或分解形式。

  • NFD:规范分解。
  • NFC:规范分解,然后是规范组成。

Canonical Composites
(有关规范化的更多信息,请参见Unicode® Standard Annex #15

在我们的案例中,我们对NFD规范化形式感兴趣,因为它使我们能够将所有组合字符与基本字符分开。

分解文本后,我们必须运行正则表达式以删除分解所产生的与组合字符相对应的所有新字符。

组合字符是旨在相对于关联基本字符定位的特殊字符。 Unicode标准区分两种类型的组合字符:空格和非间距。

我们只对非空格组合字符感兴趣。变音符号是这一组的主要班级(但不是唯一的),与拉丁,希腊和西里尔字母及其亲属一起使用。

要使用正则表达式删除非空格字符,我们必须使用\p{Mn}。该组包括all the 1,826 non-spacing characters

其他答案使用\p{InCombiningDiacriticalMarks},此块仅包括组合变音标记。它是\p{Mn}子集,仅包含112 characters

答案 3 :(得分:0)

万一有人在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