在Swift中如何从字符串中移除重音符号?

97

如何从Swift字符串中删除变音符号(或重音符号),例如将“één”更改为“een”?我必须返回到NSString,还是可以在Swift内部完成?

5个回答

196
你可以直接操作Swift的String(如果导入“Foundation”):
let foo = "één"
let bar = foo.stringByFoldingWithOptions(.DiacriticInsensitiveSearch, locale: NSLocale.currentLocale())
print(bar) // een

Swift 3:

let foo = "één"
let bar = foo.folding(options: .diacriticInsensitive, locale: .current)
print(bar) // een

一如既往的出色回答。请注意,stringByFoldingWithOptions是NSString的一个方法。它利用了Swift 2中NSString和String之间无缝桥接的特性。然而在Swift 3中情况有所不同。 - Duncan C
3
看起来跟 https://stackoverflow.com/a/16837527/1187415 相似:U-0141 大写带有斜线的 L 没有分解成基础字符和组合标记。或者(据我所了解)Unicode 标准没有定义 ŁL 之间的关系。 - Martin R
@MartinR,感谢您的快速回复。所以在Ł的情况下,我应该手动删除它吗? - mikro098
2
@RanLearns:我假设 locale: nil 将应用通用的 Unicode 规则,而 locale: .current 则应用当前语言的规则。但我还没有测试过。 - Martin R
我尝试过在结果字符串中保留空格吗? - Hide in bubble
显示剩余3条评论

23

更新@MartinR的答案...这是一个为排序/搜索提供字符串的Swift 3扩展,对某些人可能有用...

extension String {
    var forSorting: String {
        let simple = folding(options: [.diacriticInsensitive, .widthInsensitive, .caseInsensitive], locale: nil)
        let nonAlphaNumeric = CharacterSet.alphanumerics.inverted
        return simple.components(separatedBy: nonAlphaNumeric).joined(separator: "")
    }
}

需要翻译的内容已经是一个示例,不需要进行进一步的翻译。
print("Mÿ nâMe ís jÄço´B".forSorting) // "mynameisjacob"

1
你应该知道,排序非常依赖于语言环境。例如,在我的语言中,“ch”是介于“h”和“i”之间的一个字母。对于排序来说,只需使用正确的字符串搜索选项即可忽略变音符号。 - Sulthan
7
对于排序,您应该使用 localizedStandardCompare - rmaddy

10

这是我的解决方案

Swift 5

    extension String {

        func unaccent() -> String {

            return self.folding(options: .diacriticInsensitive, locale: .current)

        }

    }

8
这也可以通过应用StringTransform来完成:
let foo = "één"
let bar = foo.applyingTransform(.stripDiacritics, reverse: false)!
print(bar) // een

或者实现一个自定义属性到 StringProtocol

extension StringProtocol {
    var stripingDiacritics: String {
        applyingTransform(.stripDiacritics, reverse: false)!
    }
}

let bar = foo.stripingDiacritics
print(bar) // een

0

针对Swift 5.0.1的答案更新

func toNoSmartQuotes() -> String {
    let userInput: String = self
    return userInput.folding(options: .diacriticInsensitive, locale: .current)
}

并使用它 someTextField.text.toNoSmartQuotes()


4
请注意,这个变化比你的方法名称所暗示的要大。 - Johan Kool

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接