it-swarm.com.de

Herausfinden, ob eine Zeichenfolge numerisch ist oder nicht

Wie können wir überprüfen, ob eine Zeichenfolge nur aus Zahlen besteht. Ich nehme einen Teilstring aus einem String heraus und möchte prüfen, ob es sich um einen numerischen Teilstring handelt oder nicht.

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

Eine Möglichkeit, die sich nicht auf die begrenzte Genauigkeit des Versuchs stützt, die Zeichenfolge als Zahl zu analysieren:

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

Siehe +[NSCharacterSet decimalDigitCharacterSet] und -[NSString rangeOfCharacterFromSet:] .

229
John Calsbeek

Ich würde vorschlagen, die numberFromString:-Methode aus der NSNumberFormatter -Klasse zu verwenden, da die Zahl nicht gültig ist. Andernfalls erhalten Sie eine NSNumber.

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

Validierung durch regulären Ausdruck mit Muster "^[0-9]+$" mit der folgenden Methode -validateString:withPattern:.

[self validateString:"12345" withPattern:"^[0-9]+$"];
  1. Wenn "123.123" berücksichtigt wird
    • Mit Muster "^[0-9]+(.{1}[0-9]+)?$"
  2. Wenn genau 4 Ziffern, ohne ".".
    • Mit dem Muster "^[0-9]{4}$".
  3. Wenn Ziffern ohne "." angegeben sind und die Länge zwischen 2 ~ 5 ..__ liegt.
    • Mit dem Muster "^[0-9]{2,5}$".

Der reguläre Ausdruck kann in der Online-Website eingecheckt werden.

Die Hilfsfunktion ist wie folgt.

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

Testen Sie auf dem Spielplatz.

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

Sie können einen NSS-Scanner erstellen und die Zeichenfolge einfach scannen:

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

Check out NSScanner-Dokumentation für weitere Methoden zur Auswahl.

8
Regexident

Ich denke, der einfachste Weg, um zu überprüfen, ob jedes Zeichen in einer gegebenen Zeichenfolge numerisch ist, ist wahrscheinlich:

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

Verwenden Sie eine der anderen NSCharacterSet-Factory-Methoden, wenn Sie die zulässigen Zeichen vollständig steuern möchten.

6
Tommy

Diese ursprüngliche Frage bezog sich auf Objective-C, wurde aber auch Jahre vor der Ankündigung von Swift veröffentlicht. Wenn Sie also von Google hierher kommen und nach einer Lösung suchen, die Swift verwendet, sind Sie hier:

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

um klar zu sein, dies funktioniert für ganze Zahlen in Strings.

hier ist eine kleine Helferkategorie, die auf Johns Antwort basiert:

in .h-Datei

@interface NSString (NumberChecking)

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

@end

in .m-Datei

#import "NSString+NumberChecking.h"

@implementation NSString (NumberChecking)

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

@end

verwendungszweck:

#import "NSString+NumberChecking.h"

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

Swift 3-Lösung könnte wie folgt aussehen:

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-Lösung, wenn Sie überprüfen müssen, ob die Zeichenfolge nur Ziffern enthält:

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

John Calsbeeks Antwort ist fast korrekt, lässt aber einige Fälle von Unicode Edge aus. 

Gemäß der Dokumentation für decimalDigitCharacterSet enthält dieser Satz alle Zeichen, die von Unicode als Nd kategorisiert werden. So wird ihre Antwort unter anderem akzeptieren:

  • (U + 0967 DEVANAGARI DIGIT ONE)
  • (U + 1811 MONGOLIAN DIGIT ONE)
  • ???? (U + 1D7D9 MATHEMATICAL DOPPELSTRANKGRUPPE EINE)

Während dies in gewissem Sinne korrekt ist - jedes Zeichen in Nd wird auf eine Dezimalstelle abgebildet - ist mit Sicherheit nicht das, was der Fragesteller erwartet hat. Zum jetzigen Zeitpunkt gibt es 610 Codepunkte als Nd , von denen nur zehn die erwarteten Zeichen 0 (U + 0030) bis 9 (U + 0039) sind.

Um das Problem zu beheben, geben Sie einfach genau die Zeichen an, die akzeptabel sind:

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

Noch eine andere 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;
    }
}

Anwendungsbeispiel:

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

Wenn Sie Ziffern aus gemischten Sprachen haben, die die 0-9-Ziffernformate verwenden (oder nicht), müssen Sie einen regulären Ausdruck ausführen, der nach einer beliebigen Zahl sucht. Als nächstes müssen Sie alle Ziffern konvertieren 0-9 Format (wenn Sie den tatsächlichen Wert benötigen):

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

Für Swift 3

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

Eine Erweiterung der Antwort von@John Calsbeekund Erläuterung der Kommentare von@Jeffund@gyratory circus.

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

Die folgenden Methoden können als Kategoriemethoden fürNSStringhinzugefügt werden.

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

Der einfachste und zuverlässigste Weg ist, zu versuchen, Double zu setzen. Wenn das Ergebnis nil ist, kann es nicht zu einer legitimen Zahl geformt werden.

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]

Weitere Informationen in der Dokumentation: https://developer.Apple.com/documentation/Swift/double/2926277-init

0
Ariel

Schnelle Erweiterung:

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

Testen Sie, ob eine Zeichenfolge eine Zahl ist. Könnte hilfreich sein

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

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