सभी गैर-संख्यात्मक वर्णों को तेज़ी से एक स्ट्रिंग से निकालें


84

मुझे कुछ अज्ञात डेटा को पार्स करने की आवश्यकता है जो केवल एक संख्यात्मक मान होना चाहिए, लेकिन इसमें व्हाट्सएप या अन्य गैर-अल्फ़ान्यूमेरिक वर्ण हो सकते हैं।

क्या स्विफ्ट में ऐसा करने का एक नया तरीका है? सभी मैं ऑनलाइन पा सकते हैं चीजों को करने का पुराना सी तरीका है।

मैं देख रहा हूं stringByTrimmingCharactersInSet- जैसा कि मुझे यकीन है कि मेरे इनपुट में स्ट्रिंग के प्रारंभ या अंत में केवल व्हाट्सएप / विशेष वर्ण होंगे। वहाँ किसी भी चरित्र सेट मैं इसके लिए उपयोग कर सकते हैं? या क्या मुझे अपना खुद का निर्माण करने की आवश्यकता है?

मैं उम्मीद कर रहा था कि कुछ ऐसा होगा, stringFromCharactersInSet()जो मुझे रखने के लिए केवल मान्य वर्ण निर्दिष्ट करने की अनुमति देगा

जवाबों:


183

मैं उम्मीद कर रहा था कि stringFromCharactersInSet () की तरह कुछ होगा जो मुझे रखने के लिए केवल मान्य वर्ण निर्दिष्ट करने की अनुमति देगा।

आप या तो शुरू से या स्ट्रिंग के अंत से पात्रों को हटाने के लिए निर्धारित चरित्र के trimmingCharactersसाथ उपयोग कर सकते हैं inverted। स्विफ्ट 3 और बाद में:

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

या, यदि आप स्ट्रिंग में कहीं भी नॉन-न्यूमेरिक वर्णों को हटाना चाहते हैं (सिर्फ शुरुआत या अंत नहीं), तो आप कर सकते filterहैं characters, जैसे कि स्विफ्ट 4.2.1 में:

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

या, यदि आप स्ट्रिंग में कहीं से भी कैरेक्टरसेट से वर्ण हटाना चाहते हैं, तो उपयोग करें:

let result = String(string.unicodeScalars.filter(CharacterSet.whitespaces.inverted.contains))

या, यदि आप केवल एक निश्चित प्रारूप (जैसे ####.##) के वैध तारों से मेल खाना चाहते हैं, तो आप नियमित अभिव्यक्ति का उपयोग कर सकते हैं। उदाहरण के लिए:

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

इन विभिन्न दृष्टिकोणों का व्यवहार थोड़ा भिन्न होता है इसलिए यह ठीक उसी पर निर्भर करता है जो आप करने की कोशिश कर रहे हैं। यदि आप दशमलव संख्याएँ, या केवल पूर्णांक चाहते हैं, तो दशमलव बिंदु को शामिल या बहिष्कृत करें। इसे पूरा करने के कई तरीके हैं।


पुराने के लिए, स्विफ्ट 2 सिंटैक्स, इस उत्तर के पिछले संशोधन को देखें ।


क्या आप बता सकते हैं कि आपको invertedस्विफ्ट 3 के उदाहरण में सेट चरित्र पर करने की आवश्यकता क्यों है ?
एंडी इबेंज

4
@AndyIbanez यह कहने की तरह है, अगर "एबीसी" ऐसे किरदार हैं जिन्हें मैं रखना चाहता हूं तो वह सब कुछ ट्रिम करें जो "एबीसी" नहीं है।
स्कॉट मैकेंजी

1
स्विफ्ट में 4.2.1 let result = String(string.characters.filter { "01234567890.".characters.contains($0) })को छोटा किया जा सकता हैlet result = string.filter("01234567890.".contains)
लियो डबस

41
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
धन्यवाद! सभी Swift3 परिवर्तनों को प्राप्त करने के बाद, मुझे इस के साथ छोड़ दिया गया: myStr.replacingOccurrences (of: "[^ 0-9]", के साथ: "", विकल्प:। अनियमितExpression)
bobwki v

29

मैं इस समाधान को पसंद करता हूं , क्योंकि मुझे एक्सटेंशन पसंद हैं, और यह मुझे थोड़ा साफ लगता है। समाधान यहाँ पुन: प्रस्तुत:

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

लगता है कि स्ट्रिप
डेसिमल

18

Swift 4

मुझे एक स्ट्रिंग से केवल अल्फा न्यूमेरिक कैरेक्टर सेट करने का एक अच्छा तरीका मिला । उदाहरण के लिए:-

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

}

17

आप श्रेणियों के लिए पैटर्न मिलान ऑपरेटर का उपयोग करके स्ट्रिंग के यूनिकोडस्क्लेरव्यू को फ़िल्टर कर सकते हैं, एक यूनिकोडस्क्लेर क्लोज्डरेंज को 0 से 9 तक पास करें और परिणामी यूनिकोडस्क्लेरव्यू के साथ एक नए स्ट्रिंग को इनिशिएट करें:

extension String {
    private static var digits = UnicodeScalar("0")..."9"
    var digits: String {
        return String(unicodeScalars.filter(String.digits.contains))
    }
}

"abc12345".digits   // "12345"

संपादित करें / अद्यतन:

स्विफ्ट 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) }
    }
}

स्विफ्ट 5.2 • Xcode 11.4 या बाद का

Swift5 में हम एक नई वर्ण संपत्ति का उपयोग कर सकते हैं जिसे कहा जाता है isWholeNumber:

extension RangeReplaceableCollection where Self: StringProtocol {
    var digits: Self { filter(\.isWholeNumber) }
}

extension RangeReplaceableCollection where Self: StringProtocol {
    mutating func removeAllNonNumeric() {
        removeAll { !$0.isWholeNumber }
    }
}

एक अवधि की अनुमति देने के लिए हम चरित्र का विस्तार कर सकते हैं और एक संगणित संपत्ति बना सकते हैं:

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."

स्विफ्ट 5 के लिए बढ़िया समाधान! मैं कैसे छोड़ दूं ”। या "," स्ट्रिंग के भीतर, एक स्ट्रिंग को डबल में बदलने में सक्षम होने के लिए?
हंस बोंडोका

1
@HansBondoka इस तरह धन्यवाद filter { $0.isNumber || $0 == "." }
लियो डबस

11

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

मुझे कोई अल्फा वैल्यू नहीं चाहिए, हालाँकि मुझे कोई उम्मीद नहीं है
Dan

कृपया और स्पष्ट बताएं। हेडलाइन कहती है non-alphanumeric;-) मैंने संख्यात्मक पात्रों के लिए उत्तर संपादित किया।
vadian

8

स्विफ्ट 4

लेकिन बिना एक्सटेंशन या कंपोनेंट्स के ही सार्टरेटेडबाइचट्रैक्टर्सइन्सेट करें जो कि पढ़ा भी नहीं जाता है।

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

4

स्विफ्ट 3, संख्याओं को छोड़कर सभी को फ़िल्टर करता है

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

3

स्विफ्ट 4.2

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

2

आप ऐसा कुछ कर सकते हैं ...

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

मुझे इस बात का पूरा अंदाजा नहीं है कि स्ट्रिंग में कौन से पात्र हो सकते हैं - और मैं केवल अंत में संख्यात्मक मान चाहता हूं। इसके लिए मुझे उन सभी पात्रों को सूचीबद्ध करने की आवश्यकता होगी जिन्हें मैं नहीं चाहता .. बहुत सारे पात्र हैं जो हो सकते हैं
Dan

2

रॉब के पहले समाधान के साथ मुद्दा 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: "") } }
xaphod

2

स्विफ्ट 3

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

2
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"

1

स्विफ्ट 4.0 संस्करण

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

1

स्विफ्ट 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

एक नया UnicodeScalarView शुरू करना व्यर्थ है। फ़िल्टर का परिणाम यह पहले से ही एक यूनिकोडस्क्लेरव्यू है। return String(passed)
लियो डबस 12


0

स्विफ्ट 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
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.