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)];
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:]
.
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;
Validierung durch regulären Ausdruck mit Muster "^[0-9]+$"
mit der folgenden Methode -validateString:withPattern:
.
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"
"."
."^[0-9]{4}$"
."."
angegeben sind und die Länge zwischen 2 ~ 5 ..__ liegt."^[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;
}
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)
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.
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.
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.")
}
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");
}
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)
}
}
}
Swift 3-Lösung, wenn Sie überprüfen müssen, ob die Zeichenfolge nur Ziffern enthält:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
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
}
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]+$"];
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
}
Für Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
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ürNSString
hinzugefü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
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
} }
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
}