Ik heb de behoefte om onbekende gegevens te ontleden die alleen een numerieke waarde zouden moeten zijn, maar die spaties of andere niet-alfanumerieke tekens kunnen bevatten.
Is er een nieuwe manier om dit in Swift te doen? Alles wat ik online kan vinden, lijkt de oude C-manier om dingen te doen.
Ik kijk naar stringByTrimmingCharactersInSet
– omdat ik zeker weet dat mijn invoer alleen spaties/speciale tekens aan het begin of einde van de tekenreeks zal hebben. Zijn er ingebouwde tekensets die ik hiervoor kan gebruiken? Of moet ik er zelf een maken?
Ik hoopte dat er zoiets zou zijn als stringFromCharactersInSet()
waarmee ik alleen geldige tekens zou kunnen opgeven om te behouden
Antwoord 1, autoriteit 100%
Ik hoopte dat er zoiets zou zijn als stringFromCharactersInSet() waarmee ik alleen geldige tekens zou kunnen opgeven om te bewaren.
Je kunt ofwel trimmingCharacters
gebruiken met de inverted
tekenset om tekens aan het begin of het einde van de tekenreeks te verwijderen. In Swift 3 en hoger:
let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)
Of, als u niet-numerieke tekens ergens in de tekenreeks wilt verwijderen (niet alleen het begin of einde), kunt u filter
de characters
, b.v. in Swift 4.2.1:
let result = string.filter("0123456789.".contains)
Of, als u tekens uit een CharacterSet wilt verwijderen van waar dan ook in de string, gebruik:
let result = String(string.unicodeScalars.filter(CharacterSet.whitespaces.inverted.contains))
Of, als je alleen geldige tekenreeksen van een bepaald formaat wilt matchen (bijv. ####.##
), kun je reguliere expressie gebruiken. Bijvoorbeeld:
if let range = string.range(of: #"\d+(\.\d*)?"#, options: .regularExpression) {
let result = string[range] // or `String(string[range])` if you need `String`
}
Het gedrag van deze verschillende benaderingen verschilt enigszins, dus het hangt er gewoon van af wat je precies probeert te doen. Voeg de komma toe of sluit deze uit als u decimale getallen wilt, of alleen gehele getallen. Er zijn veel manieren om dit te bereiken.
Voor oudere Swift 2-syntaxis, zie vorige revisie van dit antwoord.
Antwoord 2, autoriteit 21%
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)
Je kunt dit antwoordupvoten.
Antwoord 3, autoriteit 15%
Ik geef de voorkeur aan deze oplossing, omdat ik van extensies houd, en het lijkt me wat schoner. Oplossing hier weergegeven:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Antwoord 4, autoriteit 10%
Je kunt de UnicodeScalarView van de string filteren met behulp van de patroonvergelijkingsoperator voor bereiken, een UnicodeScalar ClosedRange van 0 tot 9 doorgeven en een nieuwe String initialiseren met de resulterende UnicodeScalarView:
extension String {
private static var digits = UnicodeScalar("0")..."9"
var digits: String {
return String(unicodeScalars.filter(String.digits.contains))
}
}
"abc12345".digits // "12345"
bewerken/bijwerken:
Swift 4.2
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self {
return filter(("0"..."9").contains)
}
}
of als een mutatiemethode
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !("0"..."9" ~= $0) }
}
}
Swift 5.2 • Xcode 11.4 of hoger
In Swift5 kunnen we een nieuwe karaktereigenschap gebruiken met de naam isWholeNumber
:
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self { filter(\.isWholeNumber) }
}
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !$0.isWholeNumber }
}
}
Om ook een punt toe te staan, kunnen we Character uitbreiden en een berekende eigenschap maken:
extension Character {
var isDecimalOrPeriod: Bool { "0"..."9" ~= self || self == "." }
}
extension RangeReplaceableCollection where Self: StringProtocol {
var digitsAndPeriods: Self { filter(\.isDecimalOrPeriod) }
}
Speeltuin testen:
"abc12345".digits // "12345"
var str = "123abc0"
str.removeAllNonNumeric()
print(str) //"1230"
"Testing0123456789.".digitsAndPeriods // "0123456789."
Antwoord 5, autoriteit 8%
Swift 4
Ik heb een fatsoenlijke manier gevonden om alleen alfanumerieketekens uit een string te halen.
Bijvoorbeeld:-
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
}
Antwoord 6, autoriteit 5%
Een oplossing die de functie filter
en rangeOfCharacterFromSet
gebruikt
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µ
Gebruik om te filteren op alleen numerieke tekens
let string = "sld [f]34é7*˜µ"
let numericSet = "0123456789"
let filteredCharacters = string.characters.filter {
return numericSet.containsString(String($0))
}
let filteredString = String(filteredCharacters) // -> 347
of
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
Antwoord 7, autoriteit 4%
Swift 4
Maar zonder extensies of componentenSeparatedByCharactersInSet die niet zo goed leest.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
Antwoord 8, autoriteit 2%
Swift 3, filtert alles behalve nummers
let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
Antwoord 9, autoriteit 2%
Swift 4.2
let numericString = string.filter { (char) -> Bool in
return char.isNumber
}
Antwoord 10
let string = "+1*(234) fds567@-8/90-"
let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
print(onlyNumbers) // "1234567890"
of
extension String {
func removeNonNumeric() -> String {
return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined()
}
}
let onlyNumbers = "+1*(234) fds567@-8/90-".removeNonNumeric()
print(onlyNumbers)// "1234567890"
Antwoord 11
Je kunt zoiets als dit doen…
let string = "[,myString1. \"" // string : [,myString1. "
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
print(finalString)
//finalString will be "myString1"
Antwoord 12
Het probleem met Rob’s eerste oplossing is dat stringByTrimmingCharactersInSet
alleen de uiteinden van de string filtert in plaats van overal, zoals vermeld in de documentatie van Apple:
Retourneert een nieuwe tekenreeks die is gemaakt door aan beide uiteinden van de ontvangende tekens in een bepaalde tekenset te verwijderen.
Gebruik in plaats daarvan componentsSeparatedByCharactersInSet
om eerst alle niet-voorvallen van de tekenset te isoleren in arrays en ze vervolgens samen te voegen met een leeg tekenreeksscheidingsteken:
"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Wat resulteert in 123456789
Antwoord 13
Swift 3
extension String {
var keepNumericsOnly: String {
return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
}
}
Antwoord 14
Swift 4.0-versie
extension String {
var numbers: String {
return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
}
}
Antwoord 15
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
Antwoord 16
Swift 4.2
let digitChars = yourString.components(separatedBy:
CharacterSet.decimalDigits.inverted).joined(separator: "")
Antwoord 17
Swift 3-versie
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
}
}