Ios 在Swift中格式化电话号码

Ios 在Swift中格式化电话号码,ios,string,swift,uitextfield,string-formatting,Ios,String,Swift,Uitextfield,String Formatting,一旦用户开始将电话号码键入此格式类型,我将格式化我的文本文件,该格式类型为0(555)444 66 77,工作正常,但一旦我从服务器上获取号码,我就会像这样获取该号码05554446677,因此,请告诉我,一旦从服务器上获取该号码,如何以相同格式编辑该号码 我的代码一旦开始键入: func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string

一旦用户开始将电话号码键入此格式类型,我将格式化我的文本文件,该格式类型为
0(555)444 66 77
,工作正常,但一旦我从服务器上获取号码,我就会像这样获取该号码
05554446677
,因此,请告诉我,一旦从服务器上获取该号码,如何以相同格式编辑该号码

我的代码一旦开始键入:

func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {

    if textField == phoneNumberTextField{
        var newString = (textField.text as NSString).stringByReplacingCharactersInRange(range, withString: string)
        var components = newString.componentsSeparatedByCharactersInSet(NSCharacterSet.decimalDigitCharacterSet().invertedSet)

        var decimalString = "".join(components) as NSString
        var length = decimalString.length
        var hasLeadingOne = length > 0 && decimalString.characterAtIndex(0) == (1 as unichar)

        if length == 0 || (length > 11 && !hasLeadingOne) || length > 12{
            var newLength = (textField.text as NSString).length + (string as NSString).length - range.length as Int

            return (newLength > 11) ? false : true
        }
        var index = 0 as Int
        var formattedString = NSMutableString()

        if hasLeadingOne{
            formattedString.appendString("1 ")
            index += 1
        }

        if (length - index) > 1{
            var zeroNumber = decimalString.substringWithRange(NSMakeRange(index, 1))
            formattedString.appendFormat("%@ ", zeroNumber)
            index += 1
        }
        if (length - index) > 3{
            var areaCode = decimalString.substringWithRange(NSMakeRange(index, 3))
            formattedString.appendFormat("(%@) ", areaCode)
            index += 3
        }
        if (length - index) > 3{
            var prefix = decimalString.substringWithRange(NSMakeRange(index, 3))
            formattedString.appendFormat("%@ ", prefix)
            index += 3
        }
        if (length - index) > 3{
            var prefix = decimalString.substringWithRange(NSMakeRange(index, 2))
            formattedString.appendFormat("%@ ", prefix)
            index += 2
        }

        var remainder = decimalString.substringFromIndex(index)
        formattedString.appendString(remainder)
        textField.text = formattedString as String
        return false
    }else{
        return true
    }
}

使用字符串中的字符进行操作不是很简单。您需要以下信息:

Swift 2.1

let s = "05554446677"
let s2 = String(format: "%@ (%@) %@ %@ %@", s.substringToIndex(s.startIndex.advancedBy(1)),
    s.substringWithRange(s.startIndex.advancedBy(1) ... s.startIndex.advancedBy(3)),
    s.substringWithRange(s.startIndex.advancedBy(4) ... s.startIndex.advancedBy(6)),
    s.substringWithRange(s.startIndex.advancedBy(7) ... s.startIndex.advancedBy(8)),
    s.substringWithRange(s.startIndex.advancedBy(9) ... s.startIndex.advancedBy(10))
)
Swift 2.0

let s = "05554446677"
let s2 = String(format: "%@ (%@) %@ %@ %@", s.substringToIndex(advance(s.startIndex, 1)),
    s.substringWithRange(advance(s.startIndex, 1) ... advance(s.startIndex, 3)),
    s.substringWithRange(advance(s.startIndex, 4) ... advance(s.startIndex, 6)),
    s.substringWithRange(advance(s.startIndex, 7) ... advance(s.startIndex, 8)),
    s.substringWithRange(advance(s.startIndex, 9) ... advance(s.startIndex, 10))
)
代码将被打印出来
0(555)4446677

Swift 3&4 此解决方案在应用格式之前删除所有非数字字符。如果无法根据假设格式化源电话号码,则返回
nil

斯威夫特4 Swift 4解决方案解释了CharacterView的不受欢迎以及Sting与CharacterView一样成为字符集合的原因

import Foundation

func format(phoneNumber sourcePhoneNumber: String) -> String? {
    // Remove any character that is not a number
    let numbersOnly = sourcePhoneNumber.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
    let length = numbersOnly.count
    let hasLeadingOne = numbersOnly.hasPrefix("1")

    // Check for supported phone number length
    guard length == 7 || (length == 10 && !hasLeadingOne) || (length == 11 && hasLeadingOne) else {
        return nil
    }

    let hasAreaCode = (length >= 10)
    var sourceIndex = 0

    // Leading 1
    var leadingOne = ""
    if hasLeadingOne {
        leadingOne = "1 "
        sourceIndex += 1
    }

    // Area code
    var areaCode = ""
    if hasAreaCode {
        let areaCodeLength = 3
        guard let areaCodeSubstring = numbersOnly.substring(start: sourceIndex, offsetBy: areaCodeLength) else {
            return nil
        }
        areaCode = String(format: "(%@) ", areaCodeSubstring)
        sourceIndex += areaCodeLength
    }

    // Prefix, 3 characters
    let prefixLength = 3
    guard let prefix = numbersOnly.substring(start: sourceIndex, offsetBy: prefixLength) else {
        return nil
    }
    sourceIndex += prefixLength

    // Suffix, 4 characters
    let suffixLength = 4
    guard let suffix = numbersOnly.substring(start: sourceIndex, offsetBy: suffixLength) else {
        return nil
    }

    return leadingOne + areaCode + prefix + "-" + suffix
}

extension String {
    /// This method makes it easier extract a substring by character index where a character is viewed as a human-readable character (grapheme cluster).
    internal func substring(start: Int, offsetBy: Int) -> String? {
        guard let substringStartIndex = self.index(startIndex, offsetBy: start, limitedBy: endIndex) else {
            return nil
        }

        guard let substringEndIndex = self.index(startIndex, offsetBy: start + offsetBy, limitedBy: endIndex) else {
            return nil
        }

        return String(self[substringStartIndex ..< substringEndIndex])
    }
}
示例输出 蒙面数字打字 所以,这是更好的工作

"" => ""
"0" => "+0"
"412" => "+4 (12"
"12345678901" => "+1 (234) 567-8901"
"a1_b2-c3=d4 e5&f6|g7h8" => "+1 (234) 567-8"

Swift 3,但也应可翻译为Swift 4

  • 错误处理

    enum PhoneNumberFormattingError: Error {
        case wrongCharactersInPhoneNumber
        case phoneNumberLongerThanPatternAllowes
    }
    
  • 创建模式

    enum PhoneNumberFormattingPatterns: String {
        case mobile = "+xx (yxx) xxxxxxxxxxx"
        case home = "+xx (yxxx) xxxx-xxx"
    }
    
  • 插入函数

    /**
         Formats a phone-number to correct format
         - Parameter pattern: The pattern to format the phone-number.
         - Example:
            - x: Says that this should be a digit.
            - y: Says that this digit cannot be a "0".
            - The length of the pattern restricts also the length of allowed phone-number digits.
                - phone-number: "+4306641234567"
                - pattern: "+xx (yxx) xxxxxxxxxxx"
                - result: "+43 (664) 1234567"
    
         - Throws:
            - PhoneNumberFormattingError
                - wrongCharactersInPhoneNumber: if phone-number contains other characters than digits.
                - phoneNumberLongerThanPatternAllowes: if phone-number is longer than pattern allows.
         - Returns:
            - The formatted phone-number due to the pattern.
         */
    extension String {
        func vpToFormattedPhoneNumber(withPattern pattern: PhoneNumberFormattingPatterns) throws -> String {
            let phoneNumber = self.replacingOccurrences(of: "+", with: "")
            var retVal: String = ""
            var index = 0
            for char in pattern.rawValue.lowercased().characters {
                guard index < phoneNumber.characters.count else {
                    return retVal
                }
    
                if char == "x" {
                    let charIndex = phoneNumber.index(phoneNumber.startIndex, offsetBy: index)
                    let phoneChar = phoneNumber[charIndex]
                    guard "0"..."9" ~= phoneChar else {
                        throw PhoneNumberFormattingError.wrongCharactersInPhoneNumber
                    }
                    retVal.append(phoneChar)
                    index += 1
                } else if char == "y" {
                    var charIndex = phoneNumber.index(phoneNumber.startIndex, offsetBy: index)
                    var indexTemp = 1
                    while phoneNumber[charIndex] == "0" {
                        charIndex = phoneNumber.index(phoneNumber.startIndex, offsetBy: index + indexTemp)
                        indexTemp += 1
                    }
    
                    let phoneChar = phoneNumber[charIndex]
                    guard "0"..."9" ~= phoneChar else {
                        throw PhoneNumberFormattingError.wrongCharactersInPhoneNumber
                    }
                    retVal.append(phoneChar)
                    index += indexTemp
                } else {
                    retVal.append(char)
                }
            }
    
            if phoneNumber.endIndex > phoneNumber.index(phoneNumber.startIndex, offsetBy: index) {
                throw PhoneNumberFormattingError.phoneNumberLongerThanPatternAllowes
            }
    
            return retVal
        }
    }
    
  • 你可以使用这个图书馆

    范例

    let phoneFormatter = DefaultTextFormatter(textPattern: "### (###) ###-##-##")
    phoneFormatter.format("+123456789012") // +12 (345) 678-90-12
    

    使用非常简单。

    这里有很多好的答案,但我采取了完全不同的方法,我想我会与大家分享,以防有帮助

    首先,我将格式化步骤和组件分解为各自的职责

    电话号码格式通常可分为本地、国内或国际格式类型,这些格式类型因字符串长度而异

    我定义了类型:

    /// Defines the three different types of formatting phone numbers use
    ///
    /// - local: Numbers used locally.
    /// - domestic: Numbers used locally including area codes.
    /// - international: Numbers used internationally with country codes.
    public enum PhoneFormatType {
        case local
        case domestic
        case international
    }
    
    然后定义可用于格式化电话号码字符串的分隔符:

    // Defines separators that are available for use in formatting
    // phone number strings.
    public enum PhoneFormatSeparator {
        case hyphen
        case plus
        case space
        case parenthesisLH
        case parenthesisRH
        case slash
        case backslash
        case pipe
        case asterisk
    
        public var value: String {
            switch self {
            case .hyphen: return "-"
            case .plus: return "+"
            case .space: return " "
            case .parenthesisLH: return "("
            case .parenthesisRH: return ")"
            case .slash: return "/"
            case .backslash: return "\\"
            case .pipe: return "|"
            case .asterisk: return "*"
            }
        }
    }
    
    接下来,我定义了格式规则,用于指定插入分隔符(如+、-)的索引(电话号码字符串)

    // defines the separators that should be inserted in a phone number string
    // and the indexes where they should be applied
    public protocol PhoneNumberFormatRule {
    
        // the index in a phone number where this separator should be applied
        var index: Int { get set }
    
        // the priority in which this rule should be applied. Sorted in inverse, 0 is highest priority, higher numbers are lower priority
        var priority: Int { get set }
    
        // the separator to use at this index
        var separator: PhoneFormatSeparator { get set }
    }
    
    /// Default implementation of PhoneNumberFormatRule
    open class PNFormatRule: PhoneNumberFormatRule {
        public var index: Int
        public var priority: Int
        public var separator: PhoneFormatSeparator
    
        public init(_ index: Int, separator: PhoneFormatSeparator, priority: Int = 0) {
            self.index = index
            self.separator = separator
            self.priority = priority
        }
    }
    
    定义了这些规则后,我创建了将规则与给定格式类型关联的规则集

    /// Defines the rule sets associated with a given phone number type.
    /// e.g. international/domestic/local
    public protocol PhoneFormatRuleset {
    
        /// The type of phone number formatting to which these rules apply
        var type: PhoneFormatType { get set }
    
        /// A collection of rules to apply for this phone number type.
        var rules: [PhoneNumberFormatRule] { get set }
    
        /// The maximum length a number using this format ruleset should be. (Inclusive)
        var maxLength: Int { get set }
    }
    
    使用这种方式定义的所有内容,您可以快速设置规则集以适合您需要的任何格式

    下面是一个规则集示例,该规则集为美国常用的连字符格式的电话号码字符串定义了3条规则:

        // Formats phone numbers:
        //  .local: 123-4567
        //  .domestic: 123-456-7890
        //  .international: +1 234-567-8901
        static func usHyphen() -> [PhoneFormatRuleset] {
            return [
                PNFormatRuleset(.local, rules: [
                    PNFormatRule(3, separator: .hyphen)
                    ], maxLength: 7),
                PNFormatRuleset(.domestic, rules: [
                    PNFormatRule(3, separator: .hyphen),
                    PNFormatRule(6, separator: .hyphen)
                    ], maxLength: 10),
                PNFormatRuleset(.international, rules: [
                    PNFormatRule(0, separator: .plus),
                    PNFormatRule(1, separator: .space),
                    PNFormatRule(4, separator: .hyphen),
                    PNFormatRule(7, separator: .hyphen)
                    ], maxLength: 11)
            ]
        }
    
    格式化逻辑的繁重工作(并非如此)发生在这里:

    // formats a string using the format rule provided at initialization
    public func format(number: String) -> String {
    
        // strip non numeric characters
        let n = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
    
        // bail if we have an empty string, or if no ruleset is defined to handle formatting
        guard n.count > 0, let type = type(for: n.count), let ruleset = ruleset(for: type) else {
            return n
        }
    
        // this is the string we'll return
        var formatted = ""
    
        // enumerate the numeric string
        for (i,character) in n.enumerated() {
    
            // bail if user entered more numbers than allowed for our formatting ruleset
            guard i <= ruleset.maxLength else {
                break
            }
    
            // if there is a separator defined to be inserted at this index then add it to the formatted string
            if let separator = ruleset.separator(for: i) {
                formatted+=separator
            }
    
            // now append the character
            formatted+="\(character)"
        }
    
        return formatted
    } 
    
    然后使用它:

    import SwiftPhoneFormat
    
    var formatter = PhoneFormatter(rulesets: PNFormatRuleset.usParethesis())
    let formatted = formatter.format(number: numberString)
    

    非常简单的解决方案:

    extension String {
        func applyPatternOnNumbers(pattern: String, replacementCharacter: Character) -> String {
            var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
            for index in 0 ..< pattern.count {
                guard index < pureNumber.count else { return pureNumber }
                let stringIndex = String.Index(utf16Offset: index, in: pattern)
                let patternCharacter = pattern[stringIndex]
                guard patternCharacter != replacementCharacter else { continue }
                pureNumber.insert(patternCharacter, at: stringIndex)
            }
            return pureNumber
        }
    }
    

    Swift 4

    创建此函数并调用文本字段事件编辑更改

    private func formatPhone(_ number: String) -> String {
        let cleanNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
        let format: [Character] = ["X", "X", "X", "-", "X", "X", "X", "-", "X", "X", "X", "X"]
    
        var result = ""
        var index = cleanNumber.startIndex
        for ch in format {
            if index == cleanNumber.endIndex {
                break
            }
            if ch == "X" {
                result.append(cleanNumber[index])
                index = cleanNumber.index(after: index)
            } else {
                result.append(ch)
            }
        }
        return result
    }
    

    此扩展将完全满足您的要求:

     extension String {
     func convertToInternationalFormat() -> String {
        let isMoreThanTenDigit = self.count > 10
        _ = self.startIndex
        var newstr = ""
        if isMoreThanTenDigit {
            newstr = "\(self.dropFirst(self.count - 10))"
        }
        else if self.count == 10{
            newstr = "\(self)"
        }
        else {
            return "number has only \(self.count) digits"
        }
        if  newstr.count == 10 {
            let internationalString = "(\(newstr.dropLast(7))) \(newstr.dropLast(4).dropFirst(3)) \(newstr.dropFirst(6).dropLast(2)) \(newstr.dropFirst(8))"
            newstr = internationalString
        }
        return newstr
     }
     }
    
    INPUT :
    var str1 = "9253248954"
    var str2 = "+19253248954"
    var str3 = "19253248954"
    
    OUTPUT :
    str1.convertToInternationalFormat() // "(925) 324 89 54"
    str2.convertToInternationalFormat() // "(925) 324 89 54"
    str3.convertToInternationalFormat() // "(925) 324 89 54"
    

    Swift 5.1更新БааіПаааааПаааааа

    extension String {
    
        func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
            var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
            for index in 0 ..< pattern.count {
                guard index < pureNumber.count else { return pureNumber }
                let stringIndex = String.Index(utf16Offset: index, in: self)
                let patternCharacter = pattern[stringIndex]
                guard patternCharacter != replacmentCharacter else { continue }
                pureNumber.insert(patternCharacter, at: stringIndex)
            }
            return pureNumber
        }
    }
    

    如果你不想使用图书馆的话。 这里有一个链接到最佳示例,或者您可以使用下面的代码

    在Swift 5.0中设置10位电话号码格式的简单代码段,不包括一个大型库,只需实现一个委托函数和一个格式化函数:

    • UITextFieldDelegate函数
    • 格式化功能:
    func格式(电话号码:String,shouldRemoveLastDigit:Bool=false)->String{
    guard!phoneNumber.isEmpty else{return”“}
    guard let regex=try?NSRegularExpression(模式:“[\\s-\\(\\)]”,选项:。不区分大小写)else{return”“}
    设r=NSString(字符串:phoneNumber)。范围(of:phoneNumber)
    var number=regex.stringByReplacingMatches(in:phoneNumber,options:.init(rawValue:0),范围:r,withTemplate:)
    如果number.count>10{
    设tenthDigitIndex=number.index(number.startIndex,偏移量:10)
    数字=字符串(数字[number.startIndex..Swift 5

    String(
        format: "(%@) %@-%@",
        rawNumber.subString(from: 0, to: 2),
        rawNumber.subString(from: 3, to: 5),
        rawNumber.subString(from: 6, to: 9)
    )
    

    我不知道为什么,但这对我不起作用。我将textInputController.textInput设置为我的UITextField。我还在故事板的Identity inspector中设置其类TexInputField,并进行适当的转换。Field不是实时格式化的。这应该是正确的解决方案。提供了更大的灵活性,可以放置在自己的类中,并在整个过程中使用应用程序。我相信输入111222333会崩溃。虽然它不是一个有效的电话号码,但用户仍然可以输入它。感谢@sanch指出以“1”开头的10位数字的示例。这样的输入将使它通过“//检查支持的电话号码长度”下的保护。我没有考虑过这样的电话号码输入。我测试了Swift 4代码,谢天谢地,由于注释“//后缀,4个字符下的guard语句,它返回了一个零。“@sanch,我改进了代码以更好地处理以“1”开头的10个号码输入。现在guard在“//下检查支持的电话号码长度”明确拒绝这样的输入。我在示例和我自己的代码单元测试中添加了“111222333”。谢谢。恭喜!这是我见过的最好的解决方案!最好的模式解决方案如何将其用于阿拉伯数字?这绝对是我最喜欢的问题解决方案。谢谢!init(encodedOffset:)'已弃用:encodedOffset已弃用,因为最常见的用法是不正确的。电话号码极其复杂。您对其格式的任何假设都纯粹是本地的,并且肯定有大量的异常和边缘案例。请改用一个库,该库已将所有这些异常编码为国际通用。例如:Wil我在编辑中间的号码时效果不好。不幸的是,这将使用电话号码建议来阻止iOS功能。这是一个优雅的解决方案。当我想根据数字数对电话号码进行不同的格式设置时,我只是根据电话串数使用了不同的掩码。适用于Swift 4.2,只是为了在创建o时添加这一点wn掩码,如
    (XXX)XXX-XXXX
    ,它也会工作。此外,如果您需要返回普通字符串,只需创建一个类似于
    xxxxxxxxx
    的普通掩码,它会将格式化的电话号码转换回普通字符串。若要允许此操作与电话号码建议一起工作,只需将上次返回=false更改为:
    返回字符串=“”
    .iOS自动完成a
    pod 'SwiftPhoneFormat', '1.0.0'
    
    import SwiftPhoneFormat
    
    var formatter = PhoneFormatter(rulesets: PNFormatRuleset.usParethesis())
    let formatted = formatter.format(number: numberString)
    
    extension String {
        func applyPatternOnNumbers(pattern: String, replacementCharacter: Character) -> String {
            var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
            for index in 0 ..< pattern.count {
                guard index < pureNumber.count else { return pureNumber }
                let stringIndex = String.Index(utf16Offset: index, in: pattern)
                let patternCharacter = pattern[stringIndex]
                guard patternCharacter != replacementCharacter else { continue }
                pureNumber.insert(patternCharacter, at: stringIndex)
            }
            return pureNumber
        }
    }
    
    guard let text = textField.text else { return }
    textField.text = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
    
    private func formatPhone(_ number: String) -> String {
        let cleanNumber = number.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
        let format: [Character] = ["X", "X", "X", "-", "X", "X", "X", "-", "X", "X", "X", "X"]
    
        var result = ""
        var index = cleanNumber.startIndex
        for ch in format {
            if index == cleanNumber.endIndex {
                break
            }
            if ch == "X" {
                result.append(cleanNumber[index])
                index = cleanNumber.index(after: index)
            } else {
                result.append(ch)
            }
        }
        return result
    }
    
     extension String {
     func convertToInternationalFormat() -> String {
        let isMoreThanTenDigit = self.count > 10
        _ = self.startIndex
        var newstr = ""
        if isMoreThanTenDigit {
            newstr = "\(self.dropFirst(self.count - 10))"
        }
        else if self.count == 10{
            newstr = "\(self)"
        }
        else {
            return "number has only \(self.count) digits"
        }
        if  newstr.count == 10 {
            let internationalString = "(\(newstr.dropLast(7))) \(newstr.dropLast(4).dropFirst(3)) \(newstr.dropFirst(6).dropLast(2)) \(newstr.dropFirst(8))"
            newstr = internationalString
        }
        return newstr
     }
     }
    
    INPUT :
    var str1 = "9253248954"
    var str2 = "+19253248954"
    var str3 = "19253248954"
    
    OUTPUT :
    str1.convertToInternationalFormat() // "(925) 324 89 54"
    str2.convertToInternationalFormat() // "(925) 324 89 54"
    str3.convertToInternationalFormat() // "(925) 324 89 54"
    
    extension String {
    
        func applyPatternOnNumbers(pattern: String, replacmentCharacter: Character) -> String {
            var pureNumber = self.replacingOccurrences( of: "[^0-9]", with: "", options: .regularExpression)
            for index in 0 ..< pattern.count {
                guard index < pureNumber.count else { return pureNumber }
                let stringIndex = String.Index(utf16Offset: index, in: self)
                let patternCharacter = pattern[stringIndex]
                guard patternCharacter != replacmentCharacter else { continue }
                pureNumber.insert(patternCharacter, at: stringIndex)
            }
            return pureNumber
        }
    }
    
    let formattedText = text.applyPatternOnNumbers(pattern: "+# (###) ###-####", replacmentCharacter: "#")
    
        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        var fullString = textField.text ?? ""
        fullString.append(string)
        if range.length == 1 {
            textField.text = format(phoneNumber: fullString, shouldRemoveLastDigit: true)
        } else {
            textField.text = format(phoneNumber: fullString)
        }
        return false
    }
    
    func format(phoneNumber: String, shouldRemoveLastDigit: Bool = false) -> String {
        guard !phoneNumber.isEmpty else { return "" }
        guard let regex = try? NSRegularExpression(pattern: "[\\s-\\(\\)]", options: .caseInsensitive) else { return "" }
        let r = NSString(string: phoneNumber).range(of: phoneNumber)
        var number = regex.stringByReplacingMatches(in: phoneNumber, options: .init(rawValue: 0), range: r, withTemplate: "")
    
        if number.count > 10 {
            let tenthDigitIndex = number.index(number.startIndex, offsetBy: 10)
            number = String(number[number.startIndex..<tenthDigitIndex])
        }
    
        if shouldRemoveLastDigit {
            let end = number.index(number.startIndex, offsetBy: number.count-1)
            number = String(number[number.startIndex..<end])
        }
    
        if number.count < 7 {
            let end = number.index(number.startIndex, offsetBy: number.count)
            let range = number.startIndex..<end
            number = number.replacingOccurrences(of: "(\\d{3})(\\d+)", with: "($1) $2", options: .regularExpression, range: range)
    
        } else {
            let end = number.index(number.startIndex, offsetBy: number.count)
            let range = number.startIndex..<end
            number = number.replacingOccurrences(of: "(\\d{3})(\\d{3})(\\d+)", with: "($1) $2-$3", options: .regularExpression, range: range)
        }
    
        return number
    }
    
    String(
        format: "(%@) %@-%@",
        rawNumber.subString(from: 0, to: 2),
        rawNumber.subString(from: 3, to: 5),
        rawNumber.subString(from: 6, to: 9)
    )