使用*屏蔽第一个和最后一个名称字符串

时间:2016-12-19 14:21:17

标签: swift swift3

我有一个字符串,它是名字和姓氏的组合:

  

Johnny Tuck

我想在Swift 3中掩盖那个字符串:

  

J ***** T ***

我该怎么做?

3 个答案:

答案 0 :(得分:8)

你可以,例如对小写字符使用模式匹配,并将与模式匹配的字符替换为星号字符(*):

let name = "Johnny Tuck"
let pattern = Character("a")..."z"
let maskedName = String(name.characters.map { pattern ~= $0 ? Character("*") : $0 })
print(maskedName) // J***** T***

如果目的不是用*替换小写字符,而是掩盖不是给定单词中第一个的所有字符(例如,特定分隔符" "),可以通过分隔符分隔String名称,并对所有分隔的单词(子名称)的初始字符应用掩码,最后重建掩码字符串:

import Foundation
let name = "johnny  lucky tuck"
let maskedName = name.components(separatedBy: " ")
    .filter { !$0.isEmpty }.map { $0.characters }
    .map { String($0.first!).uppercased() + String(repeating: "*", count: $0.dropFirst(1).count) }
    .joined(separator: " ")
print(maskedName) // J***** L**** T***

请注意上面的uppercased(),它将初始的非屏蔽字母设置为大写字母(即使它不是最初的)。如果你不希望这个大写字母,只需删除上面的.uppercased()电话。

答案 1 :(得分:3)

一个非常简单的解决方案:

(拆分为单词,过滤掉空白单词,索引单词中的每个字符,映射到星标,再次加入全名)

let fullname = "This Is My Name"

let result = fullname
    .components(separatedBy: CharacterSet.whitespaces)
    .filter { !$0.isEmpty }
    .map { (name: String) in
        let mappedCharacters = name.characters.enumerated().map { (index, letter) in
            return (index == 0) ? letter : "*"
        }

        return String(mappedCharacters)
    }
    .joined(separator: " ")

print("Result:", result) // Result: T*** I* M* N***

答案 2 :(得分:1)

如果您打算用星号替换每个单词中除第一个单词之外的每个字符,那么这样就可以了 是另一种可能的解决方案:

extension String {
    /// Replace all characters except the first by a star.
    func starredWord() -> String {
        return String(characters.prefix(1) + characters.dropFirst().map { _ in "*" })
    }

    /// Star every "word" in a string.
    func starred() -> String {
        var result = ""
        self.enumerateSubstrings(in: startIndex..<endIndex, options: .byWords) { 
            (s, range, enclosingRange, _) in
            result +=
                // Append the substring preceeding the word ...
                self[enclosingRange.lowerBound..<range.lowerBound]
                // ... the starred word ...
                + (s?.starredWord() ?? "")
                // ... and the substring following the word.
                + self[range.upperBound..<enclosingRange.upperBound]
        }
        return result
    }
}

此处enumerateSubstrings.byWords选项一起使用 检测当前语言环境中的单词,即使它们是由分隔符组成的 标点符号。

示例:

let name = "John M. Doe, sen."
print(name.starred())
// J*** M. D**, s**.