Отфильтровать не-цифры из строки
Используя только быстрый код, я не могу понять, как взять "(555) 555-5555", вернуть только числовые значения и получить "5555555555". Мне нужно удалить все скобки, пробелы и тире. Единственные примеры, которые я могу найти, находятся в target-C, и они, кажется, все используют метод.trim(). Кажется, что у swift нет этого метода, но у него есть метод.stringByTrimmingCharacters, но это только кажется, что обрезает пробелы до и после данных.
11 ответов
Свифт 3 и 4:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Разбейте строку нецифровыми символами на массив цифр и соедините их обратно в строку:
Свифт 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("")
Свифт 3 и 4:
let newString = origString
.components(separatedBy:CharacterSet.decimalDigits.inverted)
.joined(separator: "")
Мне нравятся регулярные выражения:
var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
"\\D", withString: "", options: .RegularExpressionSearch,
range: s.startIndex..<s.endIndex)
В 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
Вот ответ Swift 2.0 от @ Tapani в виде удобного расширения String (свойство length не является частью решения, но я оставил его в качестве примера, поскольку оно также удобно):
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())
У меня была похожая проблема, но мне нужно было сохранить десятичные точки. Я подправил лучший ответ на это:
extension String {
/// Returns a string with all non-numeric characters removed
public var numericString: String {
let characterSet = CharacterSet(charactersIn: "01234567890.").inverted
return components(separatedBy: characterSet)
.joined()
}
}
подробности
xCode 8.2.1, Swift 3
идея
Удалить наборы символов из строки
Фильтровать строку в Swift
import Foundation
extension String {
private func removeCharacters(unicodeScalarsFilter: (UnicodeScalar) -> Bool) -> String {
let filtredUnicodeScalars = unicodeScalars.filter{unicodeScalarsFilter($0)}
return String(String.UnicodeScalarView(filtredUnicodeScalars))
}
private func removeCharacters(from charSets: [CharacterSet], unicodeScalarsFilter: (CharacterSet, UnicodeScalar) -> Bool) -> String {
return removeCharacters{ unicodeScalar in
for charSet in charSets {
let result = unicodeScalarsFilter(charSet, unicodeScalar)
if result {
return true
}
}
return false
}
}
func removeCharacters(charSets: [CharacterSet]) -> String {
return removeCharacters(from: charSets) { charSet, unicodeScalar in
!charSet.contains(unicodeScalar)
}
}
func removeCharacters(charSet: CharacterSet) -> String {
return removeCharacters(charSets: [charSet])
}
func onlyCharacters(charSets: [CharacterSet]) -> String {
return removeCharacters(from: charSets) { charSet, unicodeScalar in
charSet.contains(unicodeScalar)
}
}
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 [.decimalDigits, .symbols]: \(string.onlyCharacters(charSets: [.decimalDigits, .symbols]))")
print("remove .decimalDigits: \(string.removeCharacters(charSet: .decimalDigits))")
print("remove [.decimalDigits, .symbols]: \(string.removeCharacters(charSets: [.decimalDigits, .symbols]))")
Результат
Расширение для кода выше
Небольшая идея для создания быстрого фильтра. Это расширение кода, написанного выше
Расширение кода
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)")
Результат расширения кода
Попробуй это:
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
Вы хотите использовать 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)
Смотрите: пунктуация CharacterSet
Описание:
Возвращает набор символов, содержащий символы в категории пунктуации. Неформально этот набор представляет собой набор всех непробельных символов, используемых для разделения языковых единиц в сценариях, таких как точки, тире, скобки и т. Д.
Tapani Делает отличное предложение:
NSCharacterSet.decimalDigitCharacterSet().invertedSet
Точно не ответил, но выглядит как число. Я использовал 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
Вот решение @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)
Я нашел лучшее решение с функцией фильтра. Пожалуйста, посмотрите на это.
let string = "(555) 555-5555"
let onlyDigits = string.filter({ (char) -> Bool in
if Int("\(char)") != nil {
return true
}
else {
return false
}
})