Удалите все нечисловые символы из строки в swift
Мне нужно проанализировать некоторые неизвестные данные, которые должны быть просто числовыми значениями, но могут содержать пробелы или другие не алфавитно-цифровые символы.
Есть ли новый способ сделать это в Swift? Все, что я могу найти в Интернете, кажется, старый C-способ делать вещи.
Я смотрю на stringByTrimmingCharactersInSet
- так как я уверен, что мои входные данные будут иметь только пробельные/специальные символы в начале или конце строки. Существуют ли какие-либо встроенные наборы символов, которые я могу использовать для этого? Или мне нужно создать свой?
Я надеялся, что будет что-то вроде stringFromCharactersInSet()
которое позволит мне указывать только действительные символы для сохранения
Ответы
Ответ 1
Я надеялся, что будет что-то вроде stringFromCharactersInSet(), которое позволит мне указывать только действительные символы для сохранения.
Вы можете использовать trimmingCharacters
с набором символов inverted
для удаления символов из начала или конца строки. В Swift 3 и более поздних версиях:
let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "0123456789.").inverted)
Или, если вы хотите удалить нечисловые символы в любом месте строки (не только начало или конец), вы можете filter
characters
, например, в Swift 4.2.1:
let result = string.filter("0123456789.".contains)
Или, если вы хотите сопоставлять только допустимые строки определенного формата (например, ####.##
), вы можете использовать регулярное выражение. Например:
if let range = string.range(of: "\\d+(\\.\\d*)?", options: .regularExpression) {
let result = string[range] // or 'String(string[range])' if you need 'String'
}
Поведение этих разных подходов немного отличается, поэтому оно зависит только от того, что вы пытаетесь сделать. Включите или исключите десятичную точку, если вы хотите десятичные числа, или просто целые числа. Есть много способов сделать это.
Более старый синтаксис Swift 2 см. в предыдущей редакции этого ответа.
Ответ 2
let result = string.stringByReplacingOccurrencesOfString("[^0-9]", withString: "", options: NSStringCompareOptions.RegularExpressionSearch, range:nil).stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
Свифт 3
let result = string.replacingOccurrences( of:"[^0-9]", with: "", options: .regularExpression)
Вы можете проголосовать за этот ответ.
Ответ 3
Я предпочитаю это решение, потому что мне нравятся расширения, и мне кажется немного чище. Решение воспроизводится здесь:
extension String {
var digits: String {
return components(separatedBy: CharacterSet.decimalDigits.inverted)
.joined()
}
}
Ответ 4
Swift 4
Я нашел достойный способ получить только строку буквенно-цифровых символов из строки. Например:-
func getAlphaNumericValue() {
var yourString = "[email protected]#$%^&*()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
}
Ответ 5
Решение с использованием функции 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
Ответ 6
Вы можете отфильтровать 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 • Xcode 10.2
В Swift5 мы можем использовать новое свойство Character с именем isNumber
:
extension RangeReplaceableCollection where Self: StringProtocol {
var digits: Self {
return filter({ $0.isNumber })
}
}
extension RangeReplaceableCollection where Self: StringProtocol {
mutating func removeAllNonNumeric() {
removeAll { !$0.isNumber }
}
}
Тестирование игровой площадки:
"abc12345".digits // "12345"
var str = "123abc0"
str.removeAllNonNumeric()
print(str) //"1230"
Ответ 7
Swift 4
Но без расширений или компонентовSeparatedByCharactersInSet, который также не читает.
let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
Ответ 8
Swift 3, фильтрует все, кроме номеров
let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
Ответ 9
Вы можете сделать что-то вроде этого...
let string = "[,myString1. \"" // string : [,myString1. "
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("")
print(finalString)
//finalString will be "myString1"
Ответ 10
Проблема с первым решением Rob: stringByTrimmingCharactersInSet
фильтрует только концы строки, а не всюду, как указано в документации Apple:
Возвращает новую строку, выполненную путем удаления с обоих концов символов приемника, содержащихся в заданном наборе символов.
Вместо этого используйте componentsSeparatedByCharactersInSet
, чтобы сначала изолировать все невзаимодействия набора символов в массивах и впоследствии присоединиться к ним с помощью пустого разделителя строк:
"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")
Что возвращает 123456789
Ответ 11
Swift 3
extension String {
var keepNumericsOnly: String {
return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
}
}
Ответ 12
версия Swift 4.0
extension String {
var numbers: String {
return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
}
}
Ответ 13
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
Ответ 14
версия 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
}
}
Ответ 15
Swift 4.2
let digitChars = yourString.components(separatedBy:
CharacterSet.decimalDigits.inverted).joined(separator: "")
Ответ 16
Swift 4.2
let numericString = string.filter { (char) -> Bool in
return char.isNumber
}
Ответ 17
let string = "+1*(234) [email protected]/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) [email protected]/90-".removeNonNumeric()
print(onlyNumbers)// "1234567890"