Miałem nadzieję, że będzie coś takiego jak stringFromCharactersInSet (), które pozwolą mi określić tylko prawidłowe znaki do zachowania.
Możesz użyć trimmingCharacters
z inverted
zestawem znaków, aby usunąć znaki z początku lub końca łańcucha. W wersji Swift 3 i nowszych:
let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)
Albo, jeśli chcesz usunąć nienumeryczny znaków w dowolnym miejscu w ciągu (nie tylko początek lub koniec), można , np Swift 4.2.1:filter
characters
let result = string.filter("0123456789.".contains)
Lub, jeśli chcesz usunąć znaki z zestawu znaków z dowolnego miejsca w ciągu, użyj:
let result = String(string.unicodeScalars.filter(CharacterSet.whitespaces.inverted.contains))
Lub, jeśli chcesz dopasować tylko prawidłowe ciągi znaków w określonym formacie (np. ####.##
), Możesz użyć wyrażenia regularnego. Na przykład:
if let range = string.range(of: #"\d+(\.\d*)?"#, options: .regularExpression) {
let result = string[range]
}
Zachowanie tych różnych podejść nieco się różni, więc zależy tylko od tego, co dokładnie próbujesz zrobić. Uwzględnij lub wyklucz przecinek dziesiętny, jeśli chcesz mieć liczby dziesiętne lub tylko liczby całkowite. Można to osiągnąć na wiele sposobów.
W przypadku starszej składni Swift 2 zobacz poprzednią wersję tej odpowiedzi .
inverted
na zestawie znaków w przykładzie Swift 3?let result = String(string.characters.filter { "01234567890.".characters.contains($0) })
można skrócić dolet result = string.filter("01234567890.".contains)
let result = string.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Szybki 3
let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)
Możesz zagłosować za tą odpowiedzią .
źródło
Wolę to rozwiązanie , ponieważ lubię rozszerzenia i wydaje mi się trochę czystsze. Rozwiązanie odtworzone tutaj:
extension String { var digits: String { return components(separatedBy: CharacterSet.decimalDigits.inverted) .joined() } }
źródło
Znalazłem przyzwoity sposób, aby uzyskać tylko znaki alfanumeryczne ustawione z ciągu. Na przykład:-
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 }
źródło
Możesz filtrować UnicodeScalarView ciągu za pomocą operatora dopasowania wzorca dla zakresów, przekazać UnicodeScalar ClosedRange od 0 do 9 i zainicjować nowy ciąg z wynikowym UnicodeScalarView:
extension String { private static var digits = UnicodeScalar("0")..."9" var digits: String { return String(unicodeScalars.filter(String.digits.contains)) } } "abc12345".digits // "12345"
edytuj / aktualizuj:
Swift 4.2
extension RangeReplaceableCollection where Self: StringProtocol { var digits: Self { return filter(("0"..."9").contains) } }
lub jako metoda mutacji
extension RangeReplaceableCollection where Self: StringProtocol { mutating func removeAllNonNumeric() { removeAll { !("0"..."9" ~= $0) } } }
Swift 5.2 • Xcode 11.4 lub nowszy
W Swift5 możemy użyć nowej właściwości Character o nazwie
isWholeNumber
:extension RangeReplaceableCollection where Self: StringProtocol { var digits: Self { filter(\.isWholeNumber) } }
extension RangeReplaceableCollection where Self: StringProtocol { mutating func removeAllNonNumeric() { removeAll { !$0.isWholeNumber } } }
Aby uwzględnić również okres, możemy przedłużyć Character i utworzyć obliczoną właściwość:
extension Character { var isDecimalOrPeriod: Bool { "0"..."9" ~= self || self == "." } }
extension RangeReplaceableCollection where Self: StringProtocol { var digitsAndPeriods: Self { filter(\.isDecimalOrPeriod) } }
Testowanie placu zabaw:
"abc12345".digits // "12345" var str = "123abc0" str.removeAllNonNumeric() print(str) //"1230" "Testing0123456789.".digitsAndPeriods // "0123456789."
źródło
filter { $0.isNumber || $0 == "." }
.Rozwiązanie wykorzystujące
filter
funkcję irangeOfCharacterFromSet
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µ
Aby odfiltrować tylko znaki numeryczne, użyj
let string = "sld [f]34é7*˜µ" let numericSet = "0123456789" let filteredCharacters = string.characters.filter { return numericSet.containsString(String($0)) } let filteredString = String(filteredCharacters) // -> 347
lub
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
źródło
non-alphanumeric
;-) Zredagowałem odpowiedź dla znaków numerycznych.Szybki 4
Ale bez rozszerzeń lub komponentówSeparatedByCharactersInSet, który nie czyta tak dobrze.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces) let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
źródło
Swift 3, filtruje wszystkie oprócz liczb
let myString = "dasdf3453453fsdf23455sf.2234" let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil }) print(result)
źródło
Swift 4.2
let numericString = string.filter { (char) -> Bool in return char.isNumber }
źródło
Możesz zrobić coś takiego ...
let string = "[,myString1. \"" // string : [,myString1. " let characterSet = NSCharacterSet(charactersInString: "[,. \"") let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("") print(finalString) //finalString will be "myString1"
źródło
Problem z pierwszym rozwiązaniem Roba polega na
stringByTrimmingCharactersInSet
filtrowaniu tylko końców łańcucha, a nie w całości, jak stwierdzono w dokumentacji Apple:Zamiast tego użyj,
componentsSeparatedByCharactersInSet
aby najpierw wyodrębnić wszystkie niewystępujące się wystąpienia zestawu znaków w tablice, a następnie połączyć je za pomocą pustego separatora ciągu:"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Który powraca
123456789
źródło
NSCharacterSet
. Ale twoja odpowiedź jest najlepsza. Oto ogólna wersja:extension String { func removingCharactersNot(in charSet: CharacterSet) -> String { return self.components(separatedBy: charSet.inverted).joined(separator: "") } }
Szybki 3
extension String { var keepNumericsOnly: String { return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "") } }
źródło
let string = "+1*(234) fds567@-8/90-" let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() print(onlyNumbers) // "1234567890"
lub
extension String { func removeNonNumeric() -> String { return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() } } let onlyNumbers = "+1*(234) fds567@-8/90-".removeNonNumeric() print(onlyNumbers)// "1234567890"
źródło
Wersja Swift 4.0
extension String { var numbers: String { return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil }) } }
źródło
Szybki 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
źródło
return String(passed)
Swift 4.2
let digitChars = yourString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
źródło
Wersja 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 } }
źródło