2016-12-19 2 views
1

Ich habe eine Zeichenfolge, die Kombination aus Vor- und Nachname ist:Masking: Name und Vorname String mit *

Johnny Tuck

ich so die Zeichenfolge maskieren wollen in Swift 3:

J ***** T ***

Wie kann ich das tun?

+3

Bitte zeigen Sie, was Sie versucht haben. – shallowThought

+3

Was ist, wenn es einen zweiten Vornamen gibt (der abgekürzt werden kann oder nicht)? Was ist mit Fremdsprachen wie Chinesisch? –

+0

@shallowThought es ist schwer, etwas zu zeigen, wenn Sie nicht wissen, wo Sie anfangen sollen. @ mTuran das ist eine coole Frage :) – Fluidity

Antwort

8

Sie könnten z.B. verwenden Musterabgleich für Kleinbuchstaben und ersetzen diejenigen, die das Muster mit Sternchen Zeichen übereinstimmen (*):

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

Wenn der Zweck Kleinbuchstaben durch * nicht zu ersetzen, sondern vielmehr alle Zeichen zu maskieren, die nicht das erste eines gegebenen Wortes (zB ein spezifisches Trennzeichen " "), könnten Sie den Namen String durch ein Trennzeichen trennen und eine Maskierung auf alle außer dem Anfangszeichen für alle getrennten Wörter (Subnamen) anwenden, gefolgt von finally rekonstruiere die maskierte Kette:

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*** 

Notieren Sie sich oben die uppercased(), die den nicht maskierten Anfangsbuchstaben auf einen Großbuchstaben setzt (auch wenn es nicht anfänglich ist). Wenn Sie diesen oberen Fall nicht wünschen, entfernen Sie einfach den obigen Aufruf .uppercased().

+0

gute Demo der Karte. – Fluidity

+2

Wenn das erste Zeichen ein kleiner Buchstabe ist, wird es nicht richtig funktionieren, oder? –

+1

wird jedoch nicht mit diakritischen Zeichen funktionieren. – Sulthan

3

Eine sehr einfache Lösung:

(split zu Worte, herauszufiltern leere Worte, Index jedes Zeichen in Wort, Karte zu den Sternen, verbinden sie in vollen Namen wieder)

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*** 
1

Wenn Ihre Absicht ist jedes Zeichen mit Ausnahme der ersten durch einen Stern in jedem Wort zu ersetzen, dann wäre dies ein weitere mögliche Lösung sein:

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 
    } 
} 

Hier enumerateSubstrings wird mit der .byWords-Option zu verwendet, um Wörter im aktuellen Gebietsschema zu erkennen, selbst wenn sie durch Interpunktionszeichen getrennt sind.

Beispiel:

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