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)];
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:]
.
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;
Validez par expression régulière, par modèle "^[0-9]+$"
, avec la méthode suivante -validateString:withPattern:
.
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"
"."
."^[0-9]{4}$"
."."
et que la longueur est comprise entre 2 ~ 5 ..____."^[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;
}
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)
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.
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.
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.")
}
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");
}
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)
}
}
}
Swift 3 solution si besoin de vérifier que la chaîne ne comporte que des chiffres:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
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
}
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]+$"];
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
}
Pour Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
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;
}
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
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
} }
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
}