Antworten:
Hier ist eine Möglichkeit, die nicht auf der begrenzten Genauigkeit des Versuchs beruht, 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:]
.
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]]
invertedSet
, dass eine Klasse zurückgegeben wird, die den Satz umschließt, von dem sie erstellt wurde, und den entgegengesetzten Wert für alle Abfragen zurückgibt. Aber ich weiß es nicht genau.
Ich würde vorschlagen, die numberFromString:
Methode aus der NSNumberFormatter- Klasse zu verwenden. Wenn die Zahl nicht gültig ist, wird nil zurückgegeben. Andernfalls erhalten Sie eine NS-Nummer.
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
NO
für Ihre Zeichenfolge zurückkehren. Ebenfalls wissenswert: Sie kehren auch YES
für mit Leerzeichen aufgefüllte Zahlen zurück. Übrigens habe ich Ihrer Antwort gerade ein aktuelles Code-Snippet hinzugefügt, hoffe, es macht Ihnen nichts aus.
Validieren Sie durch regulären Ausdruck, nach Muster "^[0-9]+$"
mit der folgenden Methode -validateString:withPattern:
.
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"
"."
.
"^[0-9]{4}$"
."."
und die Länge zwischen 2 ~ 5 liegt.
"^[0-9]{2,5}$"
."^-?\d+$"
Der reguläre Ausdruck kann auf der Online-Website überprüft 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;
}
Test 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)
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 }
Und ich habe einen Fehler bekommenPlayground execution aborted: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
return matchRange.location != NSNotFound;
^-?\d+$
, ich habe es auf der Website überprüft: regex101.com
Sie können einen NSScanner erstellen und einfach die Zeichenfolge scannen:
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
Schauen Sie sich NSScanner Dokumentation für weitere Methoden zur Auswahl.
isAtEnd
.
Ich denke, der einfachste Weg, um zu überprüfen, ob jedes Zeichen in einer bestimmten 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 vollständige Kontrolle über akzeptable Zeichen wünschen.
Diese ursprüngliche Frage betraf 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, können Sie Folgendes tun:
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.")
}
Swift 3-Lösung, wenn überprüft werden muss, ob die Zeichenfolge nur Ziffern enthält:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
.inverted
und anderen Aktionen macht.
Dies funktioniert für Ganzzahlen in Zeichenfolgen.
Hier ist eine kleine Hilfskategorie basierend auf Johns Antwort oben:
in der .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
Verwendung:
#import "NSString+NumberChecking.h"
if([someString isNumber]) {
NSLog(@"is a number");
}else {
NSLog(@"not a number");
}
Die 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)
}
}
}
Die Antwort von John Calsbeek ist fast richtig, lässt jedoch einige Unicode- Randfälle aus .
Gemäß der Dokumentation für enthältdecimalDigitCharacterSet
dieser Satz alle Zeichen, die von Unicode als kategorisiert wurden Nd
. So wird ihre Antwort unter anderem akzeptieren:
१
(U + 0967 DEVANAGARI DIGIT ONE)᠑
(U + 1811 MONGOLIAN DIGIT ONE)𝟙
(U + 1D7D9 MATHEMATICAL DOUBLE-STRUCK DIGIT ONE)Während dies in gewissem Sinne richtig ist - jedes Zeichen in Nd
wird einer Dezimalstelle zugeordnet -, ist es mit ziemlicher Sicherheit nicht das, was der Fragesteller erwartet hat. Zum jetzigen Zeitpunkt gibt es 610 Codepunkte, die als kategorisiert sindNd
, 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 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]+$"];
Eine Erweiterung der Antwort von @John Calsbeek und eine Klarstellung der Kommentare von @Jeff und @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;
}
Folgendes kann als Kategoriemethode für hinzugefügt werden 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;
}
Testen Sie, ob eine Zeichenfolge eine Zahl ist
int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;
if (i == NSNotFound) {
//is a number
}
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
} }
Für Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 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 in 0- konvertieren. 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
}
Der einfachste und zuverlässigste Weg ist der Versuch, so zu wirken, als Double
ob das Ergebnis nil
- es kann 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 finden Sie in der Dokumentation: https://developer.apple.com/documentation/swift/double/2926277-init
.
Zeichen