web-dev-qa-db-ja.com

swiftの文字列からすべての非数値文字を削除します

数値である必要がありますが、空白またはその他の英数字以外の文字が含まれている可能性がある未知のデータを解析する必要があります。

Swiftでこれを行う新しい方法はありますか?私がオンラインで見つけることができるのは、物事を行う古いCの方法のようです。

私はstringByTrimmingCharactersInSetを見ています-私の入力には文字列の先頭または末尾に空白/特殊文字のみが含まれていると確信しています。これに使用できる組み込みの文字セットはありますか?または、自分で作成する必要がありますか?

stringFromCharactersInSet()のようなものがあり、有効な文字のみを指定して保持できることを期待していました。

59
Dan

保持する有効な文字のみを指定できるstringFromCharactersInSet()のようなものがあることを望んでいました。

trimmingCharactersinverted文字セットとともに使用して、文字列の先頭または末尾から文字を削除できます。 Swift 3以降:

let result = string.trimmingCharacters(in: CharacterSet(charactersIn: "01234567890.").inverted)

または、文字列の任意の場所(開始または終了だけでなく)で数字以外の文字を削除する場合は、filter the charactersを使用できます。 Swift 4.2.1で:

let result = string.filter("01234567890.".contains)

または、特定の形式(例:####.##)の有効な文字列のみに一致させたい場合は、正規表現を使用できます。例えば:

if let range = string.range(of: "\\d+(\\.\\d*)?", options: .regularExpression) {
    let result = string[range] // or `String(string[range])` if you need `String`
}

これらの異なるアプローチの振る舞いはわずかに異なるため、あなたが何をしようとしているかに正確に依存しています。 10進数または整数のみが必要な場合は、小数点を含めるか除外します。これを実現する方法はたくさんあります。


古いSwift 2構文については、 この回答の以前のリビジョン を参照してください。

118
Rob
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)

この回答 に投票できます。

34
Tom Howard

この解決策 の方が好きです。なぜなら拡張機能が好きだからです。ここに再現されたソリューション:

extension String {
    var digits: String {
        return components(separatedBy: CharacterSet.decimalDigits.inverted)
            .joined()
    }
}
21
Jake Cronin

Swift 4

文字列からget only alpha numeric characters setを取得する適切な方法を見つけました。例えば:-

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

}
12
Aashish

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
10
vadian

範囲のパターンマッチング演算子を使用して文字列のUnicodeScalarViewをフィルタリングし、0〜9のUnicodeScalar ClosedRangeを渡し、結果の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では、isNumberという新しいCharacterプロパティを使用できます。

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"
9
Leo Dabus

Swift 4

ただし、拡張機能またはcomponentsSeparatedByCharactersInSetがなければ読み取りもできません。

let allowedCharSet = NSCharacterSet.letters.union(.whitespaces)
let filteredText = String(sourceText.unicodeScalars.filter(allowedCharSet.contains))
5
Steve Moser

Swift 3、数字以外のすべてをフィルタリング

let myString = "dasdf3453453fsdf23455sf.2234"
let result = String(myString.characters.filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
print(result)
4
CodeOverRide

このようなことができます...

let string = "[,myString1. \"" // string : [,myString1. " 
let characterSet = NSCharacterSet(charactersInString: "[,. \"")
let finalString = (string.componentsSeparatedByCharactersInSet(characterSet) as NSArray).componentsJoinedByString("") 
print(finalString)   
//finalString will be "myString1"
2
vivek takrani

Robの最初のソリューションの問題は、stringByTrimmingCharactersInSetが、Appleのドキュメントに記載されているように、文字列全体ではなく文字列の末尾のみをフィルタリングすることです。

指定された文字セットに含まれるレシーバー文字の両端から削除して作成された新しい文字列を返します。

代わりに componentsSeparatedByCharactersInSet を使用して、最初に文字セットのすべての非出現を配列に分離し、その後、空の文字列セパレーターでそれらを結合します。

"$$1234%^56()78*9££".componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "0123456789").invertedSet)).joinWithSeparator("")

123456789を返します

2
Ryan Brodie

スイフト3

extension String {
    var keepNumericsOnly: String {
        return self.components(separatedBy: CharacterSet(charactersIn: "0123456789").inverted).joined(separator: "")
    }
}
2
Ehab Saifan

Swift 4.0バージョン

extension String {
    var numbers: String {
        return String(describing: filter { String($0).rangeOfCharacter(from: CharacterSet(charactersIn: "0123456789")) != nil })
    }
}
1
rockdaswift

スイフト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
1

Swift 4.2

let numericString = string.filter { (char) -> Bool in
    return char.isNumber
}
0
mef27

Swift 4.2

let digitChars  = yourString.components(separatedBy:
        CharacterSet.decimalDigits.inverted).joined(separator: "")
0
Debaprio B
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"
0

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
    }
}
0
hhamm