swift2 - programacion - Eliminar todos los caracteres no numéricos de una cadena de forma rápida
tipos de datos en swift (17)
Esperaba que hubiera algo como stringFromCharactersInSet () que me permitiría especificar solo caracteres válidos para mantener.
Puede usar
trimmingCharacters
con el juego de caracteres
inverted
para eliminar los caracteres del inicio o el final de la cadena.
En Swift 3 y posterior:
let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "01234567890.").inverted)
O, si desea eliminar caracteres no numéricos en cualquier parte de la cadena (no solo el inicio o el final), puede
filter
los
characters
, por ejemplo, en Swift 4.2.1:
let result = string.filter("01234567890.".contains)
O bien, si solo desea hacer coincidir cadenas válidas de cierto formato (por ejemplo,
####.##
), puede usar una expresión regular.
Por ejemplo:
if let range = string.range(of: "//d+(//.//d*)?", options: .regularExpression) {
let result = string[range] // or `String(string[range])` if you need `String`
}
El comportamiento de estos diferentes enfoques difiere ligeramente, por lo que solo depende exactamente de lo que está tratando de hacer. Incluya o excluya el punto decimal si desea números decimales, o solo enteros. Hay muchas formas de lograr esto.
Para la sintaxis Swift 2 anterior , consulte la revisión anterior de esta respuesta .
Tengo la necesidad de analizar algunos datos desconocidos que deberían ser solo un valor numérico, pero que pueden contener espacios en blanco u otros caracteres no alfanuméricos.
¿Hay una nueva forma de hacer esto en Swift? Todo lo que puedo encontrar en línea parece ser la vieja forma C de hacer las cosas.
Estoy mirando
stringByTrimmingCharactersInSet
, ya que estoy seguro de que mis entradas solo tendrán espacios en blanco / caracteres especiales al comienzo o al final de la cadena.
¿Hay algún juego de caracteres incorporado que pueda usar para esto?
¿O necesito crear el mío?
Esperaba que hubiera algo como
stringFromCharactersInSet()
que me permitiría especificar solo caracteres válidos para mantener
Swift 4
Encontré una manera decente de obtener solo caracteres alfanuméricos establecidos de una cadena. Por ejemplo:-
func getAlphaNumericValue() {
var yourString = "123456789!@#$%^&*()AnyThingYouWant"
let unsafeChars = CharacterSet.alphanumerics.inverted // Remove the .inverted to get the opposite result.
let cleanChars = yourString.components(separatedBy: unsafeChars).joined(separator: "")
print(cleanChars) // 123456789AnyThingYouWant
}
Swift 4
String.swift
import Foundation
extension String {
func removeCharacters(from forbiddenChars: CharacterSet) -> String {
let passed = self.unicodeScalars.filter { !forbiddenChars.contains($0) }
return String(String.UnicodeScalarView(passed))
}
func removeCharacters(from: String) -> String {
return removeCharacters(from: CharacterSet(charactersIn: from))
}
}
ViewController.swift
let character = "1Vi234s56a78l9"
let alphaNumericSet = character.removeCharacters(from: CharacterSet.decimalDigits.inverted)
print(alphaNumericSet) // will print: 123456789
let alphaNumericCharacterSet = character.removeCharacters(from: "0123456789")
print("no digits",alphaNumericCharacterSet) // will print: Vishal
El problema con la primera solución de Rob es
stringByTrimmingCharactersInSet
solo filtra los extremos de la cadena en lugar de todo, como se indica en la documentación de Apple:
Devuelve una nueva cadena hecha mediante la eliminación de ambos extremos de los caracteres del receptor contenidos en un conjunto de caracteres dado.
En su lugar, utilice
componentsSeparatedByCharactersInSet
para aislar primero todas las no ocurrencias del conjunto de caracteres en matrices y luego unirlas con un separador de cadenas vacío:
"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Que devuelve
123456789
Prefiero esta solución , porque me gustan las extensiones, y me parece un poco más limpia. Solución reproducida aquí:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Puede filtrar el UnicodeScalarView de la cadena utilizando el operador de coincidencia de patrones para rangos, pasar un UnicodeScalar ClosedRange de 0 a 9 e inicializar una nueva cadena con el UnicodeScalarView resultante:
extension String {
private static var digits = UnicodeScalar("0")..."9"
var digits: String {
return String(unicodeScalars.filter(String.digits.contains))
}
}
"abc12345".digits // "12345"
editar / actualizar:
Swift 4.2
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self {
return filter(("0"..."9").contains)
}
}
o como un método de mutación
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !("0"..."9" ~= $0) }
}
}
editar / actualizar:
Swift 5 • Xcode 10.2
En Swift5 podemos usar una nueva propiedad Character llamada
isNumber
:
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self {
return filter({ $0.isNumber })
}
}
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !$0.isNumber }
}
}
Prueba en el patio de recreo:
"abc12345".digits // "12345"
var str = "123abc0"
str.removeAllNonNumeric()
print(str) //"1230"
Puedes hacer algo como esto ...
let string = "[,myString1. /"" // string : [,myString1. "
let characterSet = NSCharacterSet(charactersInString: "[,. /"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
print(finalString)
//finalString will be "myString1"
Swift 3
extension String {
var keepNumericsOnly: String {
return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
}
}
Swift 3, filtra todos excepto los números
let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
Swift 4.2
let numericString = string.filter { (char) -> Bool in
return char.isNumber
}
Una solución que utiliza la función de
filter
y
rangeOfCharacterFromSet
let string = "sld [f]34é7*˜µ"
let alphaNumericCharacterSet = NSCharacterSet.alphanumericCharacterSet()
let filteredCharacters = string.characters.filter {
return String($0).rangeOfCharacterFromSet(alphaNumericCharacterSet) != nil
}
let filteredString = String(filteredCharacters) // -> sldf34é7µ
Para filtrar solo caracteres numéricos, use
let string = "sld [f]34é7*˜µ"
let numericSet = "0123456789"
let filteredCharacters = string.characters.filter {
return numericSet.containsString(String($0))
}
let filteredString = String(filteredCharacters) // -> 347
o
let numericSet : [Character] = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
let filteredCharacters = string.characters.filter {
return numericSet.contains($0)
}
let filteredString = String(filteredCharacters) // -> 347
Versión Swift 4.0
extension String {
var numbers: String {
return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
}
}
Swift 4
Pero sin extensiones o componentesSeparatedByCharactersInSet que no se lee tan bien.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
Swift 4.2
let digitChars = yourString.components(separatedBy:
CharacterSet.decimalDigits.inverted).joined(separator: "")
Versión Swift 3
extension String
{
func trimmingCharactersNot(in charSet: CharacterSet) -> String
{
var s:String = ""
for unicodeScalar in self.unicodeScalars
{
if charSet.contains(unicodeScalar)
{
s.append(String(unicodeScalar))
}
}
return s
}
}
let result = string.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Swift 3
let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)
Puedes votar esta respuesta .
let string = "+1*(234) fds567@-8/90-"
let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
print(onlyNumbers) // "1234567890"
o
extension String {
func removeNonNumeric() -> String {
return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
}
}
let onlyNumbers = "+1*(234) fds567@-8/90-".removeNonNumeric()
print(onlyNumbers)// "1234567890"