यह पता लगाना कि कोई स्ट्रिंग संख्यात्मक है या नहीं


93

हम कैसे जांच सकते हैं कि क्या एक स्ट्रिंग केवल संख्याओं से बना है। मैं एक स्ट्रिंग से एक सबस्ट्रिंग निकाल रहा हूं और यह जांचना चाहता हूं कि यह न्यूमेरिक सबस्ट्रिंग है या नहीं।

NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];

जवाबों:


241

यहां एक तरीका है जो स्ट्रिंग को एक संख्या के रूप में पार्स करने के सीमित परिशुद्धता पर भरोसा नहीं करता है:

NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
    // newString consists only of the digits 0 through 9
}

देखें +[NSCharacterSet decimalDigitCharacterSet]और -[NSString rangeOfCharacterFromSet:]


6
यह @ 231.123 "" के लिए सच है: // newString में केवल अंक 0 के 9 और .चरित्र के होते हैं
निकोलस टायलर

5
NSMutableCharacterSet * digitsAndDots = [NSMutableCharacterSet दशमलवDigitCharacterSet]; [digitsAndDots addCharactersInString: @ ";"]; NSCharacterSet * notDigitsNorDots = [digitsAndDots invertedSet]; //, "इन्वर्टेडसेट" में लाने के लिए धन्यवाद। मैं अपने अस्तित्व के बारे में पता नहीं था
codrut

5
नोट: यह विधि @ "" को एक संख्या मानती है; यदि लागू हो, तो आपको [newString lenght]> 0. की भी जांच करनी होगी। कृपया मुझे बताएं कि क्या मैं गलत हूं।
markckim

2
@Supertecnoboff ऐसा लगता है कि यह आईओएस में बदल गया है। यह सुनिश्चित करने के बजाय इस्तेमाल किया जा सकता है:[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]]
निकोलस टायलर

2
@KMGorbunov मुझे नहीं लगता कि NSCharacterSet वास्तव में एक बैकिंग सेट का भंडारण कर रहा है जिसमें सेट में प्रत्येक एकल वर्ण शामिल है। मुझे संदेह invertedSetहै कि एक वर्ग वापस आ रहा है जो सेट किए गए फॉर्म को लपेटता है, और सभी प्रश्नों के लिए विपरीत मूल्य देता है। लेकिन मुझे कुछ पता नहीं है।
बजे जॉन कलसेबेक

33

मैं NSNumberFormatter वर्ग numberFromString:से विधि का उपयोग करने का सुझाव देता हूं , जैसे कि संख्या मान्य नहीं है, यह शून्य वापस आ जाएगी; अन्यथा, यह आपको एक NSNumber लौटा देगा।

NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;

क्या आप सुनिश्चित हैं कि यह @ 124sbd "के लिए एक वैध संख्या नहीं लौटाएगा?"
टॉमी

नहीं, NSNumberFormatter और NSScanner दोनों ही NOआपके तार के लिए लौटेंगे । यह भी जानने लायक: वे YESव्हॉट्सएप के साथ गद्देदार संख्या के लिए भी लौटते हैं । Btw, मैंने अभी आपके उत्तर में कुछ वास्तविक कोड स्निपेट जोड़े हैं, आशा है कि आपको कोई आपत्ति नहीं है।
२२:१२ पर रेगेक्सिडेंट

NSScanner को उस स्ट्रिंग के लिए 'यस' को प्रलेखन के अनुसार वापस करना चाहिए, जिसमें "एक वैध पूर्णांक प्रतिनिधित्व" पाया गया हो। इसके अलावा, यह वास्तव में iOS 4.3.2 पर एक परीक्षण में किया था। हालाँकि, NSNumberFormatter ने शून्य लौटाया।
टॉमी

यह पकड़ नहीं है '।' जो मेरे लिए एक आवश्यकता है। @ जॉन कालसेक से जवाब ने अच्छी तरह से काम किया।
डेमियन

सैकड़ों अक्षरों वाले सभी अंकों के साथ एक स्ट्रिंग के लिए क्या होता है? क्या NSNumber बनाने की कोई सीमा है?
बिन्नीऊ

11

"^[0-9]+$"निम्नलिखित विधि के साथ, पैटर्न द्वारा नियमित अभिव्यक्ति द्वारा मान्य करें -validateString:withPattern:

[self validateString:"12345" withPattern:"^[0-9]+$"];
  1. यदि "123.123" माना जाता है
    • पैटर्न के साथ "^[0-9]+(.{1}[0-9]+)?$"
  2. यदि बिल्कुल 4 अंकों की संख्या, बिना "."
    • पैटर्न के साथ "^[0-9]{4}$"
  3. यदि अंक बिना संख्या के हैं ".", और लंबाई 2 ~ 5 के बीच है।
    • पैटर्न के साथ "^[0-9]{2,5}$"
  4. माइनस साइन के साथ: "^-?\d+$"

ऑनलाइन वेब साइट में नियमित अभिव्यक्ति की जांच की जा सकती है ।

सहायक कार्य निम्नलिखित है।

// Validate the input string with the given pattern and
// return the result as a boolean
- (BOOL)validateString:(NSString *)string withPattern:(NSString *)pattern
{
    NSError *error = nil;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];

    NSAssert(regex, @"Unable to create regular expression");

    NSRange textRange = NSMakeRange(0, string.length);
    NSRange matchRange = [regex rangeOfFirstMatchInString:string options:NSMatchingReportProgress range:textRange];

    BOOL didValidate = NO;

    // Did we find a matching range
    if (matchRange.location != NSNotFound)
        didValidate = YES;

    return didValidate;
}

स्विफ्ट 3 संस्करण:

खेल के मैदान में टेस्ट।

import UIKit
import Foundation

func validate(_ str: String, pattern: String) -> Bool {
    if let range = str.range(of: pattern, options: .regularExpression) {
        let result = str.substring(with: range)
        print(result)
        return true
    }
    return false
}

let a = validate("123", pattern: "^-?[0-9]+")
print(a)

मैंने स्विफ्ट 3 के लिए इस तरह की कोशिश की। func numberOnly(string: String) -> Int { let expression = "" let regex = NSRegularExpression.init(pattern: expression, options: .caseInsensitive) let numberOfMatches = regex.numberOfMatches(in: string, options: .reportProgress, range: NSRange.init(location: 0, length: string.characters.count)) if numberOfMatches == 0 { return Int(string)! } return 0 }और मुझे त्रुटि मिलीPlayground execution aborted: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
माथी अरसन

मुझे नहीं पता कि स्विफ्ट के लिए एक सही 3. अगर मैं गलत हूं तो मुझे सुधारो।
मत्ती अरसन

कैसे के बारे में बसreturn matchRange.location != NSNotFound;
LimeRed

माइनस साइन के बारे में क्या?
थॉमस

@ थोमस के साथ ^-?\d+$, मैंने इसे साइट पर सत्यापित किया: regex101.com
AechoLiu

9

आप एक NSScanner बना सकते हैं और बस स्ट्रिंग को स्कैन कर सकते हैं:

NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];

की जाँच करें NSScanner के प्रलेखन अधिक तरीकों से चुनने के लिए।


क्या यह नहीं बताया जाएगा कि कम से कम पहला वर्ण संख्यात्मक है या नहीं?
टॉमी

मेरी गलती। के लिए अंतिम कॉल भूल गया isAtEnd
रेक्सिडेंट

6

मुझे लगता है कि यह जांचने का सबसे आसान तरीका है कि किसी दिए गए स्ट्रिंग में प्रत्येक वर्ण संख्यात्मक है:

NSString *trimmedString = [newString stringByTrimmingCharactersInSet:[NSCharacterSet decimalDigitCharacterSet]];

if([trimmedString length])
{
    NSLog(@"some characters outside of the decimal character set found");
}
else
{
    NSLog(@"all characters were in the decimal character set");
}

यदि आप स्वीकार्य वर्णों पर पूर्ण नियंत्रण चाहते हैं, तो अन्य NSCharacterSet फ़ैक्टरी विधियों में से एक का उपयोग करें।


मुझे यह तरीका पसंद है। हालाँकि यह बहुत साफ नहीं लगता है, यह जाँचने का एक बहुत ही आसान और मुख्य आधार-अनुकूल तरीका है यदि NSString में "गैर-अंक" हैं। + मुझे लगता है कि यह किसी भी अन्य रोबोट-आधारित तरीकों की तुलना में बहुत तेज है (हालांकि हम शायद यहां प्रदर्शन में ज्यादा नहीं दिख रहे हैं)।
१०:४

मेरा मानना ​​है कि stringByTrimmingCharactersInet केवल स्ट्रिंग की शुरुआत और अंत को दर्शाता है
Brody Robertson

@ ब्रॉडी रॉबर्टसन: यह करता है। जो इस उत्तर के लिए मामूली नहीं है। आपको क्या लगता है कि यह परीक्षा किसके लिए असफल होगी?
टॉमी

@ टॉमी, पुनर्मूल्यांकन के बाद मैं आपके उत्तर को समझता हूं और यह मान्य है और आगे बढ़ेगा, लेकिन आपको मुझे संपादित करने की अनुमति देने के लिए संपादित करने की आवश्यकता है
Brody Robertson

6

यह मूल प्रश्न ऑब्जेक्टिव-सी के बारे में था, लेकिन स्विफ्ट की घोषणा के वर्षों पहले भी इसे पोस्ट किया गया था। इसलिए, यदि आप Google से यहां आ रहे हैं और ऐसे समाधान की तलाश कर रहे हैं जो स्विफ्ट का उपयोग करे, तो आप यहां जाएं:

let testString = "12345"
let badCharacters = NSCharacterSet.decimalDigitCharacterSet().invertedSet

if testString.rangeOfCharacterFromSet(badCharacters) == nil {
    print("Test string was a number")
} else {
    print("Test string contained non-digit characters.")
}

6

यदि स्विफ्ट में केवल अंक हैं, तो 3 समाधान स्विफ्ट करें:

CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))

1
साफ और अच्छा, सबसे अच्छा समाधान। मुझे यह पसंद है कि यह अनावश्यक .invertedऔर अन्य कार्य नहीं करता है ।
डेनी पी

4

स्पष्ट होना, स्ट्रिंग्स में पूर्णांकों के लिए यह कार्य करता है।

जॉन के उत्तर के आधार पर एक छोटा सहायक श्रेणी

.ह फ़ाइल

@interface NSString (NumberChecking)

+(bool)isNumber:(NSString *)string;

@end

इन .m फ़ाइल

#import "NSString+NumberChecking.h"

@implementation NSString (NumberChecking)

+(bool)isNumber {
    if([self rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location == NSNotFound) {
        return YES;
    }else {
        return NO;
    }
}

@end

उपयोग:

#import "NSString+NumberChecking.h"

if([someString isNumber]) {
    NSLog(@"is a number");
}else {
    NSLog(@"not a number");
}

4

स्विफ्ट 3 समाधान इस तरह हो सकता है:

extension String {

    var doubleValue:Double? {
        return NumberFormatter().number(from:self)?.doubleValue
    }

    var integerValue:Int? {
        return NumberFormatter().number(from:self)?.intValue
    }

    var isNumber:Bool {
        get {
            let badCharacters = NSCharacterSet.decimalDigits.inverted
            return (self.rangeOfCharacter(from: badCharacters) == nil)
        }
    }
}

2

जॉन कलसेबेक का उत्तर लगभग सही है लेकिन कुछ यूनिकोड किनारे के मामलों को छोड़ देता है।

प्रति के लिए दस्तावेज़decimalDigitCharacterSet , कि सेट के रूप में यूनिकोड द्वारा वर्गीकृत सभी पात्रों में शामिल हैं Nd। इस प्रकार उनका जवाब दूसरों के बीच में स्वीकार करेंगे:

  • (U + 0967 देवनागरी डिजिटल एक)
  • (U + 1811 मंगोलियाई DIGIT वन)
  • 𝟙 (U + 1D7D9 मैथेमेटिकल डबेल-स्ट्रक्च डिजिटल एक)

हालांकि कुछ अर्थों में यह सही है - प्रत्येक चरित्र Ndएक दशमलव अंक में मैप करता है - यह लगभग निश्चित रूप से नहीं है जो पूछने वाले की उम्मीद है। इस लेखन के रूप में वहाँ हैं 610 कोड बिंदुओं को वर्गीकृत किया गया हैNd , जिनमें से केवल दस अक्षर 0(U + 0030) हैं9 ) हैं।

समस्या को ठीक करने के लिए, बस उन वर्णों को निर्दिष्ट करें जो स्वीकार्य हैं:

NSCharacterSet* notDigits = 
    [[NSCharacterSet characterSetWithCharactersInString:@"0123456789"] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
    // newString consists only of the digits 0 through 9
}

1

फिर भी एक और विकल्प:

- (BOOL)isValidNumber:(NSString*)text regex:(NSString*)regex {
    @try {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
        return [predicate evaluateWithObject:text];
    }
    @catch (NSException *exception) {
        assert(false); 
        return NO;
    }
}

उपयोग उदाहरण:

BOOL isValid = [self isValidNumber:@"1234" regex:@"^[0-9]+$"];

1

@ जॉन्स केल्बेक के उत्तर का विस्तार , और @ जेफ़ और @ सर्जिकल सर्कस की टिप्पणियों का स्पष्टीकरण ।

+ (BOOL)doesContainDigitsOnly:(NSString *)string
{
    NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

    BOOL containsDigitsOnly = [string rangeOfCharacterFromSet:nonDigits].location == NSNotFound;

    return containsDigitsOnly;
}

+ (BOOL)doesContainNonDigitsOnly:(NSString *)string
{
    NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];

    BOOL containsNonDigitsOnly = [string rangeOfCharacterFromSet:digits].location == NSNotFound;

    return containsNonDigitsOnly;
}

निम्नलिखित को श्रेणी विधियों के रूप में जोड़ा जा सकता है NSString

- (BOOL)doesContainDigitsOnly
{
    NSCharacterSet *nonDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

    BOOL containsDigitsOnly = [self rangeOfCharacterFromSet:nonDigits].location == NSNotFound;

    return containsDigitsOnly;
}

- (BOOL)doesContainNonDigitsOnly
{
    NSCharacterSet *digits = [NSCharacterSet decimalDigitCharacterSet];

    BOOL containsNonDigitsOnly = [self rangeOfCharacterFromSet:digits].location == NSNotFound;

    return containsNonDigitsOnly;
}

0

यदि एक स्ट्रिंग एक संख्या है तो परीक्षण करें सहायक हो सकता है

int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;

if (i == NSNotFound) {
     //is a number
}

0

स्विफ्ट एक्सटेंशन:

extension NSString {
func isNumString() -> Bool {
    let numbers = NSCharacterSet(charactersInString: "0123456789.").invertedSet
    let range = self.rangeOfCharacterFromSet(numbers).location
    if range == NSNotFound {
        return true
    }
    return false
}  }

0

स्विफ्ट 3 के लिए

var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
  // String only consist digits 0-9
}

0

जब आपके पास अंक हैं जो मिश्रित भाषाओं से हैं , तो 0-9 अंकों के प्रारूप का उपयोग करें (या न करें), आपको एक regex चलाने की आवश्यकता होगी जो किसी भी संख्या को खोजेगा, अगली बात सभी अंकों को 0- में बदलना है। 9 प्रारूप (यदि आपको वास्तविक मूल्य की आवश्यकता है):

// Will look for any language digits
let regex = try NSRegularExpression(pattern: "[^[:digit:]]", options: .caseInsensitive)
let digitsString = regex.stringByReplacingMatches(in: string,
                                                         options: NSRegularExpression.MatchingOptions(rawValue: 0),
                                                         range: NSMakeRange(0, string.count), withTemplate: "")
// Converting the digits to be 0-9 format
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "EN")
let finalValue = numberFormatter.number(from: digitsString)

if let finalValue = finalValue {
  let actualValue = finalValue.doubleValue
}

0

सबसे आसान और सबसे भरोसेमंद तरीका यह है कि Doubleयदि कोई परिणाम हो, तो वह कास्ट करने की कोशिश कर रहा है nil- इसे वैध संख्या में नहीं बनाया जा सकता है।

let strings = ["test", "123", "123.2", "-123", "123-3", "123..22", ".02"]
let validNumbers = strings.compactMap(Double.init)

print(validNumbers)
// prints [123.0, 123.2, -123.0, 0.02]

प्रलेखन में अधिक जानकारी: https://developer.apple.com/documentation/swift/double/2926277-init


0

सरल ने स्ट्रिंग विस्तार से लिखा:

extension String {
    var isNumeric: Bool {
        return self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.