Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //: Playground - noun: a place where people can play
- import UIKit
- struct EmailInfo {
- struct Guessed {
- var firstname: String? = nil {
- didSet {
- if firstname != nil && firstname!.characters.count < 2 {
- firstname = nil
- }
- }
- }
- var lastname: String? = nil {
- didSet {
- if lastname != nil && lastname!.characters.count < 2 {
- lastname = nil
- }
- }
- }
- // TODO:
- // var companyName: String? = nil // better results if your target is professional, work with school too
- // TODO: what can we guess from the extension (top level domain) ? country or lang ?
- }
- let email: String
- // splitted email
- let local: String
- let hostname: String
- let ext: String
- var guessed = Guessed()
- private init(email: String) {
- self.email = email
- var emailComponents = email.components(separatedBy: "@")
- let domain = emailComponents.popLast()!
- local = emailComponents.joined(separator: "@") // email local part can have arobase in it
- var domainComponents = domain.components(separatedBy: ".")
- hostname = domainComponents.removeFirst()
- ext = domainComponents.joined(separator: ".") // extension can contains multiple points
- }
- mutating func guessFirstNameAndLastName(filterOnlyFirstnameOnCommonProviders: Bool = true) {
- // we remove non alphabetics char and use them to split into potential names
- let alpha = "qwertyuiopasdfghjklzxcvbnm"
- let charToIgnore = NSCharacterSet(charactersIn: alpha + alpha.uppercased()).inverted
- let components = local.components(separatedBy: charToIgnore)
- let firstComponentIsSingleLetter: Bool = components.first!.characters.count == 1
- // we remove initials because we can do nothing from them
- var filteredComponents = components.filter({ (component) -> Bool in
- return component.characters.count > 1
- })
- guard filteredComponents.count > 0 else {
- return
- }
- guessed.firstname = filteredComponents.removeFirst()
- if filteredComponents.count == 0 && firstComponentIsSingleLetter { // handle case j.smith@icloud.com
- guessed.lastname = guessed.firstname
- guessed.firstname = nil
- } else {
- guessed.lastname = filteredComponents.joined(separator: " ")
- }
- if filterOnlyFirstnameOnCommonProviders &&
- guessed.firstname != nil &&
- guessed.lastname == nil &&
- (hostname.contains("mail") || EmailInfo.commonMailProviders.contains(hostname)) {
- // we only have firstname and hostname is common -> we probably are wrong so we delete it
- guessed.firstname = nil
- }
- }
- mutating func updateFirstnameKnowing(lastname lastName: String)
- {
- guard guessed.lastname != lastName else {
- return
- }
- if guessed.firstname == nil && guessed.lastname == nil {
- guessFirstNameAndLastName(filterOnlyFirstnameOnCommonProviders: false)
- }
- if guessed.firstname == lastName { // order was wrong -> we invert both exemple : smith.john@gmail.com
- guessed.firstname = guessed.lastname
- } else if guessed.firstname?.contains(lastName) ?? false { // both are in one string without separator exemple : johnsmith@gmail.com
- guessed.firstname = guessed.firstname?.replacingOccurrences(of: lastName, with: "")
- }
- guessed.lastname = lastName
- }
- mutating func updateLastnameKnowing(firstname firstName: String)
- {
- guard guessed.firstname != firstName else {
- return
- }
- if guessed.firstname == nil && guessed.lastname == nil {
- guessFirstNameAndLastName(filterOnlyFirstnameOnCommonProviders: false)
- }
- if guessed.lastname == firstName { // order was wrong -> we invert both exemple : smith.john@gmail.com
- guessed.lastname = guessed.firstname
- } else if guessed.firstname?.contains(firstName) ?? false && guessed.firstname != firstName { // both are in one string without separator (mean the only component we found is in first name) exemple : johnsmith@gmail.com
- guessed.lastname = guessed.firstname?.replacingOccurrences(of: firstName, with: "")
- } else if guessed.lastname == nil && guessed.firstname?.characters.first == firstName.characters.first {
- guessed.lastname = guessed.firstname
- guessed.lastname?.characters.removeFirst()
- }
- guessed.firstname = firstName
- }
- static let commonMailProviders = ["yahoo", "outlook", "live", "icloud"] // + anything containing "mail" in it (gmail, hotmail, yopmail, caramail, ...)
- static func guessInfo(from email: String, knownInfo: Guessed? = nil) -> EmailInfo {
- var emailInfo = EmailInfo(email: email)
- if (knownInfo?.lastname == nil || knownInfo?.firstname == nil) {
- emailInfo.guessFirstNameAndLastName()
- if let lastname = knownInfo?.lastname {
- emailInfo.updateFirstnameKnowing(lastname: lastname)
- } else if let firstname = knownInfo?.firstname {
- emailInfo.updateLastnameKnowing(firstname: firstname)
- }
- } else {
- emailInfo.guessed.firstname = knownInfo?.firstname
- emailInfo.guessed.lastname = knownInfo?.lastname
- }
- return emailInfo
- }
- }
- var emails = [ // common mail formats to test
- "j-s@hotmail.fr", // nothing we can do
- "john@company.fr", // OK
- "john.k.smith@gmail.com", // OK
- "john@smith.fr", // uncommon ? john@company.fr is more common so we don't try to handle this case
- "john.smith@gmail.com", // OK
- "john.smith42@gmail.com", // OK
- "john.smith.42@gmail.com", // OK
- "johnsmith@gmail.com", // good after update, guess nothing when provider is common
- "smithjohn@gmail.com", // good after update, guess nothing when provider is common
- "smith.john@gmail.com", // good after update, best we can do
- "j.smith@yahoo.com", // best we can do
- "jsmith@icloud.com" // good after update, guess nothing when provider is common
- ]
- for email in emails {
- print("email : " + email)
- var info = EmailInfo.guessInfo(from: email)
- print("firsname : " + (info.guessed.firstname ?? ""))
- print("lastname : " + (info.guessed.lastname ?? ""))
- print("-- update with firstname known as John")
- info.updateLastnameKnowing(firstname: "john")
- print("firsname : " + (info.guessed.firstname ?? ""))
- print("lastname : " + (info.guessed.lastname ?? ""))
- print("-- update with lastname known as Smith")
- info = EmailInfo.guessInfo(from: email)
- info.updateFirstnameKnowing(lastname: "smith")
- print("firsname : " + (info.guessed.firstname ?? ""))
- print("lastname : " + (info.guessed.lastname ?? ""))
- print("-----------")
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement