Подтвердить что ты не робот

Удалите все нечисловые символы из строки в swift

Мне нужно проанализировать некоторые неизвестные данные, которые должны быть просто числовыми значениями, но могут содержать пробелы или другие не алфавитно-цифровые символы.

Есть ли новый способ сделать это в Swift? Все, что я могу найти в Интернете, кажется, старый C-способ делать вещи.

Я смотрю на stringByTrimmingCharactersInSet - так как я уверен, что мои входные данные будут иметь только пробельные/специальные символы в начале или конце строки. Существуют ли какие-либо встроенные наборы символов, которые я могу использовать для этого? Или мне нужно создать свой?

Я надеялся, что будет что-то вроде stringFromCharactersInSet() которое позволит мне указывать только действительные символы для сохранения

4b9b3361

Ответ 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"