【问题标题】:Filter non-digits from string从字符串中过滤非数字
【发布时间】:2015-04-30 15:16:03
【问题描述】:

仅使用快速代码我无法弄清楚如何获取“(555)555-5555”并仅返回数值并获得“5555555555”。我需要删除所有括号、空格和破折号。我能找到的唯一示例是在 Objective-C 中,它们似乎都使用 .trim() 方法。似乎 swift 没有这种方法,但它确实有 .stringByTrimmingCharacters 方法,但这似乎只是修剪数据前后的空白。

【问题讨论】:

  • 所有“trim”方法都不起作用,因为它们只会从字符串的末尾删除字符。

标签: swift string numbers


【解决方案1】:

Swift 3 和 4

extension String {
    var digits: String {
        return components(separatedBy: CharacterSet.decimalDigits.inverted)
            .joined()
    }
}

斯威夫特 5

你应该可以省略return

还有: 请阅读@onmyway133 的评论以提醒您注意

【讨论】:

【解决方案2】:

通过非数字字符将字符串拆分为数字数组,然后将它们连接回字符串:

斯威夫特 1:

let stringArray = origString.componentsSeparatedByCharactersInSet(
    NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = NSArray(array: stringArray).componentsJoinedByString("")

斯威夫特 2:

let stringArray = origString.componentsSeparatedByCharactersInSet(
    NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")

Swift 3 和 4:

let newString = origString
    .components(separatedBy:CharacterSet.decimalDigits.inverted)
    .joined()

【讨论】:

  • 倒转十进制数字字符集的想法不错。
  • 这节省了我一些时间,作为建议,第二行可以简单地替换为 stringArray.joinWithSeperator("")
  • 不过滤掉 '&' 或 '$' !
【解决方案3】:

我喜欢正则表达式:

var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
    "\\D", withString: "", options: .RegularExpressionSearch, 
    range: s.startIndex..<s.endIndex)

【讨论】:

  • 感谢您的回答!一个小的补充:我发现一个更好的正则表达式是[^\\d+],保持有效的+字符不变。
【解决方案4】:

在 Swift 4 中解决方案更好:

import Foundation

let sourceText = "+5 (555) 555-5555"

let allowedCharset = CharacterSet
    .decimalDigits
    .union(CharacterSet(charactersIn: "+"))

let filteredText = String(sourceText.unicodeScalars.filter(allowedCharset.contains))

print(filteredText) // +55555555555

【讨论】:

    【解决方案5】:

    这是@Tapani 的 Swift 2.0 答案,作为一个方便的字符串扩展,(长度属性不是解决方案的一部分,但我将它留在示例中,因为它也很方便):

    import Foundation
    
    extension String {
    
        var length : Int {
            return self.characters.count
        }
    
        func digitsOnly() -> String{
            let stringArray = self.componentsSeparatedByCharactersInSet(
                NSCharacterSet.decimalDigitCharacterSet().invertedSet)
            let newString = stringArray.joinWithSeparator("")
    
            return newString
        }
    
    }
    

    用法:

    let phone = "(123)-123 - 1234"
    print(phone.digitsOnly())
    

    【讨论】:

      【解决方案6】:

      我遇到了类似的问题,但我需要保留小数点。我调整了对此的最佳答案:

      extension String {
      
          /// Returns a string with all non-numeric characters removed
          public var numericString: String {
              let characterSet = CharacterSet(charactersIn: "0123456789.").inverted
              return components(separatedBy: characterSet)
                  .joined()
          }
      }
      

      【讨论】:

        【解决方案7】:

        详情

        • Xcode 版本 10.2.1 (10E1001),Swift 5

        解决方案

        import Foundation
        
        extension String {
        
            private func filterCharacters(unicodeScalarsFilter closure: (UnicodeScalar) -> Bool) -> String {
                return String(String.UnicodeScalarView(unicodeScalars.filter { closure($0) }))
            }
        
            private func filterCharacters(definedIn charSets: [CharacterSet], unicodeScalarsFilter: (CharacterSet, UnicodeScalar) -> Bool) -> String {
                if charSets.isEmpty { return self }
                let charSet = charSets.reduce(CharacterSet()) { return $0.union($1) }
                return filterCharacters { unicodeScalarsFilter(charSet, $0) }
            }
        
            func removeCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { !$0.contains($1) } }
            func removeCharacters(charSet: CharacterSet) -> String { return removeCharacters(charSets: [charSet]) }
        
            func onlyCharacters(charSets: [CharacterSet]) -> String { return filterCharacters(definedIn: charSets) { $0.contains($1) } }
            func onlyCharacters(charSet: CharacterSet) -> String { return onlyCharacters(charSets: [charSet]) }
        }
        

        用法

        let string = "23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
        print("original string:                                 \(string)")
        print("only .decimalDigits:                             \(string.onlyCharacters(charSet: .decimalDigits))")
        print("only [.lowercaseLetters, .symbols]:              \(string.onlyCharacters(charSets: [.lowercaseLetters, .symbols]))")
        print("remove .letters:                                 \(string.removeCharacters(charSet: .letters))")
        print("remove [.decimalDigits, .lowercaseLetters]:      \(string.removeCharacters(charSets: [.decimalDigits, .lowercaseLetters]))")
        

        结果

        original string:                                 23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
        only .decimalDigits:                             2345425241309499238304
        only [.lowercaseLetters, .symbols]:              fgdorivwer+wiuruwu$q+dgnkvljb`keflnwdlqsa`
        remove .letters:                                 2345#@%#425  24 1+ 30949*()92_)$#)_ 38304+{ `; `,.
        remove [.decimalDigits, .lowercaseLetters]:      #@%#   +DWEJ *()ER_)$I#Q)_ U+RFJO{ `; `WKFSA,.E
        

        (可选)字符串扩展

        extension String {
            var onlyDigits: String { return onlyCharacters(charSets: [.decimalDigits]) }
            var onlyLetters: String { return onlyCharacters(charSets: [.letters]) }
        }
        

        (可选)字符串扩展用法

        let string = "23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E"
        print("original string:     \(string)")
        print(".onlyDigits:         \(string.onlyDigits)")
        print(".onlyLetters:        \(string.onlyLetters)")
        

        (可选)字符串扩展使用结果

        original string:     23f45gdor#@%#i425v wer 24 1+DWEJwi 3u09ru49w*()9uE2R_)$I#Q)_ U383q04+RFJO{dgnkvlj b`kefl;nwdl qsa`WKFSA,.E
        .onlyDigits:         2345425241309499238304
        .onlyLetters:        fgdorivwerDWEJwiuruwuERIQUqRFJOdgnkvljbkeflnwdlqsaWKFSAE
        

        【讨论】:

          【解决方案8】:

          试试这个:

          let string = "(555) 555-5555"
          let digitString = string.filter { ("0"..."9").contains($0) }
          print(digitString) // 5555555555
          

          加入扩展:

          extension String
          {
              var digitString: String { filter { ("0"..."9").contains($0) } }
          }
          
          print("(555) 555-5555".digitString) // 5555555555
          

          【讨论】:

            【解决方案9】:

            你会想要使用 NSCharacterSet:

            查看这个 NSHipster 链接以了解 Swift 和 Obj-C 实现: http://nshipster.com/nscharacterset/

            类似的例子:

            var string = "  Lorem    ipsum dolar   sit  amet. "
            
            let components = string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).filter({!isEmpty($0)})
            
            string = join(" ", components)
            

            参见:punctuationCharacterSet

            说明:

            返回一个字符集,其中包含标点符号类别中的字符。 通俗地说,这个集合是所有非空白字符的集合,用于分隔脚本中的语言单位,例如句点、破折号、括号等。

            @Tapani 提出一个很好的建议:NSCharacterSet.decimalDigitCharacterSet().invertedSet

            【讨论】:

              【解决方案10】:

              这是@Tapani Swift 3.2 解决方案

              let phno = contact.phoneNumbers[0].phoneNumber
              let strarr = phno.components(separatedBy: NSCharacterSet.decimalDigits.inverted)
              let newString = NSArray(array: strarr).componentsJoined(by: "")
              print(newString)
              

              【讨论】:

                【解决方案11】:

                没有完全回答,但它看起来像一个数字。 我使用 URLComponents 来构建 url,因为它会自动去除括号和破折号:

                var telUrl: URL? {
                    var component = URLComponents()
                    component.scheme = "tel"
                    component.path = "+49 (123) 1234 - 56789"
                    return component.url
                }
                

                然后

                UIApplication.shared.open(telUrl, options: [:], completionHandler: nil)
                

                致电+49 123 123456789

                【讨论】:

                  【解决方案12】:

                  我找到了带有过滤功能的最佳解决方案。请看一下。

                  let string = "(555) 555-5555"
                  
                  let onlyDigits = string.filter({ (char) -> Bool in
                  
                      if Int("\(char)") != nil {
                  
                          return true
                      }
                      else {
                  
                          return false
                      }
                  
                  })
                  

                  【讨论】:

                  • let onlyDigits = string.filter{ Int("\($0)") != nil }
                  • 让 onlyDigits = string.filter{ch in "0123456789".contains(ch)}
                  • @altimes 这会增加运行时的复杂性。
                  • 有趣的想法。我假设解析和构造 Int 会更复杂。但是,看着它,它只有一个字符可以处理,可能在幕后对 ascii 值进行了一些简单的操作。
                  猜你喜欢
                  • 2019-02-25
                  • 2013-06-14
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2013-08-12
                  相关资源
                  最近更新 更多