web-dev-qa-db-fra.com

Savoir si une chaîne est numérique ou non

Comment pouvons-nous vérifier si une chaîne est composée uniquement de nombres. Je sors une sous-chaîne d'une chaîne et je veux vérifier si c'est une sous-chaîne numérique ou non.

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

Voici un moyen qui ne repose pas sur la précision limitée de l'analyse syntaxique de la chaîne:

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

Voir +[NSCharacterSet decimalDigitCharacterSet] et -[NSString rangeOfCharacterFromSet:] .

229
John Calsbeek

Je suggérerais d'utiliser la méthode numberFromString: à partir de NSNumberFormatter class, comme si le nombre n'était pas valide, le résultat serait nul; sinon, il vous retournera un NSNumber.

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

Validez par expression régulière, par modèle "^[0-9]+$", avec la méthode suivante -validateString:withPattern:.

[self validateString:"12345" withPattern:"^[0-9]+$"];
  1. Si "123.123" est considéré
    • Avec motif "^[0-9]+(.{1}[0-9]+)?$"
  2. Si exactement 4 chiffres, sans ".".
    • Avec le motif "^[0-9]{4}$".
  3. Si les chiffres sont des chiffres sans "." et que la longueur est comprise entre 2 ~ 5 ..____.
    • Avec le motif "^[0-9]{2,5}$".

L'expression régulière peut être cochée le site Web en ligne .

La fonction d'assistance est la suivante.

// 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;
}

Swift 3 version:

Test dans la cour de récréation.

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)
10
AechoLiu

Vous pouvez créer un scanner NSS et numériser simplement la chaîne:

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

Consultez la documentation de NSScanner pour plus de méthodes à choisir.

8
Regexident

Je pense que le moyen le plus simple de vérifier que chaque caractère d'une chaîne donnée est numérique est probablement:

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");
}

Utilisez l'une des autres méthodes de fabrique NSCharacterSet si vous souhaitez un contrôle complet sur les caractères acceptables.

6
Tommy

Cette question initiale concernait Objective-C, mais elle a également été publiée des années avant l'annonce de Swift. Donc, si vous venez de Google et cherchez une solution utilisant Swift, voici ce que vous devez faire:

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.")
}
5
TwoStraws

pour être clair, cela fonctionne pour les entiers dans les chaînes.

heres une petite catégorie d'aide basée sur la réponse de John ci-dessus:

dans le fichier .h

@interface NSString (NumberChecking)

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

@end

dans le fichier .m

#import "NSString+NumberChecking.h"

@implementation NSString (NumberChecking)

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

@end

usage:

#import "NSString+NumberChecking.h"

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

La solution Swift 3 pourrait ressembler à:

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)
        }
    }
}
4
hhamm

Swift 3 solution si besoin de vérifier que la chaîne ne comporte que des chiffres:

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

La réponse de John Calsbeek est presque correcte mais omet certains cas Unicode Edge. 

Selon le documentation pour decimalDigitCharacterSet , cet ensemble inclut tous les caractères classés par Unicode comme étant Nd. Ainsi, leur réponse acceptera, entre autres:

  • (U + 0967 DEVANAGARI DIGIT ONE)
  • (U + 1811 MONGOLIAN DIGIT ONE)
  • ???? (U + 1D7D9 NUMÉRO UN MATHÉMATIQUE AJOURÉ)

Bien que, dans un certain sens, cela soit correct - chaque caractère dans Nd correspond à un chiffre décimal - ce n'est certainement pas ce à quoi le demandeur s'attendait. Au moment de la rédaction de ce document, il y a 610 points de code classés dans la catégorie Nd , dont dix seulement sont les caractères attendus 0 (U + 0030) à 9 (U + 0039).

Pour résoudre le problème, spécifiez simplement les caractères acceptables:

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

Encore une autre option:

- (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;
    }
}

Exemple d'utilisation:

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

Lorsque vous avez des chiffres qui proviennent de langues mixtes , qui utilisent (ou non) les formats de 0 à 9 chiffres, vous devrez exécuter une expression régulière qui recherchera un nombre quelconque. La prochaine étape consiste à convertir tous les chiffres. être au format 0-9 (si vous avez besoin de la valeur réelle):

// 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
OhadM

Pour Swift 3

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

Une extension de la réponse de@John Calsbeeket une clarification des commentaires de@Jeffet@gyratory.

+ (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;
}

Les éléments suivants peuvent être ajoutés comme méthodes de catégorie pourNSString

- (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

Le moyen le plus simple et le plus fiable consiste à transtyper Double, si le résultat est nil - il ne peut pas être transformé en un nombre légitime.

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]

Plus d'informations dans la documentation: https://developer.Apple.com/documentation/Swift/double/2926277-init

0
Ariel

Extension rapide:

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
Bhavesh Patel

Teste si une chaîne est un nombre qui pourrait être utile

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

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