swift - entero - Filtrar no dígitos de la cadena
int to string swift 4 (11)
Usando solo el código rápido no puedo entender cómo tomar "(555) 555-5555" y devolver solo los valores numéricos y obtener "5555555555". Necesito eliminar todos los paréntesis, espacios en blanco y el guión. Los únicos ejemplos que puedo encontrar están en el objetivo C y todos parecen usar el método .trim (). Parece que swift no tiene este método pero tiene el método .stringByTrimmingCharacters, pero eso solo parece recortar los espacios en blanco antes y después de los datos.
Detalles
xCode 8.2.1, Swift 3
Idea
Eliminar los conjuntos de caracteres de la cadena
Filtrar cadena en 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])
}
}
Uso
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]))")
Resultado
Extensión para el código anterior
Una pequeña idea para el filtro rápido de creación. Esta es una extensión del código escrito arriba
Extensión de código
extension String {
var onlyDigits: String {
return onlyCharacters(charSets: [.decimalDigits])
}
var onlyLetters: String {
return onlyCharacters(charSets: [.letters])
}
}
Uso de la extensión de código
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)")
Resultado de extensión de código
Aquí está la respuesta Swift 2.0 de @Tapani como una práctica extensión String, (la propiedad length no es parte de la solución, pero la dejé en el ejemplo porque también es útil):
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
}
}
Uso:
let phone = "(123)-123 - 1234"
print(phone.digitsOnly())
Aquí está la solución @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)
Divida la cadena por caracteres que no sean de dígitos en una matriz de dígitos y vuélvalos a una cadena:
Swift 1:
let stringArray = origString.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = NSArray(array: stringArray).componentsJoinedByString("")
Swift 2:
let stringArray = origString.componentsSeparatedByCharactersInSet(
NSCharacterSet.decimalDigitCharacterSet().invertedSet)
let newString = stringArray.joinWithSeparator("")
Swift 3 y 4:
let newString = origString
.components(separatedBy:CharacterSet.decimalDigits.inverted)
.joined(separator: "")
En Swift 4 la solución es más agradable:
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
Encontré la mejor solución con la función de filtro. Por favor, eche un vistazo.
let string = "(555) 555-5555"
let onlyDigits = string.filter({ (char) -> Bool in
if Int("/(char)") != nil {
return true
}
else {
return false
}
})
Me gustan las expresiones regulares:
var s = "(555) 555-5555"
s = s.stringByReplacingOccurrencesOfString(
"//D", withString: "", options: .RegularExpressionSearch,
range: s.startIndex..<s.endIndex)
No exactamente respondida, pero parece un número. Usé URLComponents para construir la url porque elimina los paréntesis y los guiones automáticamente:
var telUrl: URL? {
var component = URLComponents()
component.scheme = "tel"
component.path = "+49 (123) 1234 - 56789"
return component.url
}
entonces
UIApplication.shared.open(telUrl, options: [:], completionHandler: nil)
llama al +49 123 123456789
Querrá usar NSCharacterSet:
Consulte este enlace de NSHipster para implementaciones de Swift y Obj-C: http://nshipster.com/nscharacterset/
Ejemplo similar:
var string = " Lorem ipsum dolar sit amet. "
let components = string.componentsSeparatedByCharactersInSet(NSCharacterSet.whitespaceCharacterSet()).filter({!isEmpty($0)})
string = join(" ", components)
Ver: puntuacionCharacterSet
Descripción:
Devuelve un conjunto de caracteres que contiene los caracteres en la categoría de Puntuación. De manera informal, este conjunto es el conjunto de todos los caracteres que no son espacios en blanco utilizados para separar unidades lingüísticas en scripts, como períodos, guiones, paréntesis, etc.
hace una gran sugerencia:
NSCharacterSet.decimalDigitCharacterSet().invertedSet
Swift 3 y 4:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Tuve un problema similar, pero necesitaba retener los puntos decimales. Ajusté la respuesta principal a esto:
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()
}
}