Мне нужно проанализировать некоторые неизвестные данные, которые должны быть просто числовыми, но могут содержать пробелы или другие не буквенно-цифровые символы.
Есть ли новый способ сделать это в Swift? Все, что я могу найти в Интернете, похоже, это старый способ работы на C.
Я смотрю stringByTrimmingCharactersInSet
- поскольку я уверен, что мои входные данные будут иметь только пробелы / специальные символы в начале или в конце строки. Могу ли я использовать для этого какие-либо встроенные наборы символов? Или мне нужно создать свою?
Я надеялся, что будет что-то вроде того, stringFromCharactersInSet()
что позволит мне указать только допустимые символы для сохранения
inverted
это с набором символов в примере Swift 3?let result = String(string.characters.filter { "01234567890.".characters.contains($0) })
можно сократить доlet result = string.filter("01234567890.".contains)
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)
Вы можете проголосовать за этот ответ .
источник
Я предпочитаю это решение , потому что мне нравятся расширения, и мне оно кажется немного чище. Решение воспроизведено здесь:
extension String { var digits: String { return components(separatedBy: CharacterSet.decimalDigits.inverted) .joined() } }
источник
Я нашел достойный способ получить из строки только буквенно-цифровые символы . Например:-
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 }
источник
Вы можете отфильтровать UnicodeScalarView строки с помощью оператора сопоставления с образцом для диапазонов, передать UnicodeScalar ClosedRange от 0 до 9 и инициализировать новую строку с полученным UnicodeScalarView:
extension String { private static var digits = UnicodeScalar("0")..."9" var digits: String { return String(unicodeScalars.filter(String.digits.contains)) } } "abc12345".digits // "12345"
изменить / обновить:
Swift 4.2
extension RangeReplaceableCollection where Self: StringProtocol { var digits: Self { return filter(("0"..."9").contains) } }
или как метод мутации
extension RangeReplaceableCollection where Self: StringProtocol { mutating func removeAllNonNumeric() { removeAll { !("0"..."9" ~= $0) } } }
Swift 5.2 • Xcode 11.4 или новее
В Swift5 мы можем использовать новое свойство Character, которое называется
isWholeNumber
:extension RangeReplaceableCollection where Self: StringProtocol { var digits: Self { filter(\.isWholeNumber) } }
extension RangeReplaceableCollection where Self: StringProtocol { mutating func removeAllNonNumeric() { removeAll { !$0.isWholeNumber } } }
Чтобы разрешить период, мы можем расширить Character и создать вычисляемое свойство:
extension Character { var isDecimalOrPeriod: Bool { "0"..."9" ~= self || self == "." } }
extension RangeReplaceableCollection where Self: StringProtocol { var digitsAndPeriods: Self { filter(\.isDecimalOrPeriod) } }
Тестирование детской площадки:
"abc12345".digits // "12345" var str = "123abc0" str.removeAllNonNumeric() print(str) //"1230" "Testing0123456789.".digitsAndPeriods // "0123456789."
источник
filter { $0.isNumber || $0 == "." }
.Решение с использованием
filter
функции и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µ
Чтобы отфильтровать только числовые символы, используйте
let string = "sld [f]34é7*˜µ" let numericSet = "0123456789" let filteredCharacters = string.characters.filter { return numericSet.containsString(String($0)) } let filteredString = String(filteredCharacters) // -> 347
или же
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
источник
non-alphanumeric
;-) Я редактировал ответ для числовых символов.Swift 4
Но без расширений или компонентовSeparatedByCharactersInSet, которые также не читаются.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces) let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
источник
Swift 3, фильтрует все, кроме чисел
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 }
источник
Вы можете сделать что-то вроде этого ...
let string = "[,myString1. \"" // string : [,myString1. " let characterSet = NSCharacterSet(charactersInString: "[,. \"") let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("") print(finalString) //finalString will be "myString1"
источник
Проблема с первым решением Роба заключается в
stringByTrimmingCharactersInSet
фильтрации только концов строки, а не всей строки, как указано в документации Apple:Вместо этого используйте,
componentsSeparatedByCharactersInSet
чтобы сначала изолировать все не вхождения набора символов в массивы, а затем объединить их с помощью пустого разделителя строк:"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Что возвращается
123456789
источник
NSCharacterSet
. Но ваш ответ лучший. Вот общая версия:extension String { func removingCharactersNot(in charSet: CharacterSet) -> String { return self.components(separatedBy: charSet.inverted).joined(separator: "") } }
Swift 3
extension String { var keepNumericsOnly: String { return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "") } }
источник
let string = "+1*(234) fds567@-8/90-" let onlyNumbers = string.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() print(onlyNumbers) // "1234567890"
или же
extension String { func removeNonNumeric() -> String { return self.components(separatedBy: CharacterSet.decimalDigits.inverted).joined() } } let onlyNumbers = "+1*(234) fds567@-8/90-".removeNonNumeric() print(onlyNumbers)// "1234567890"
источник
Версия Swift 4.0
extension String { var numbers: String { return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil }) } }
источник
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
источник
return String(passed)
Swift 4.2
let digitChars = yourString.components(separatedBy: CharacterSet.decimalDigits.inverted).joined(separator: "")
источник
Версия 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 } }
источник