找出字符串是否为数字

时间:2011-05-22 23:04:57

标签: iphone objective-c cocoa-touch ios nsstring

我们如何检查字符串是否仅由数字组成。我从字符串中取出一个子字符串,并想检查它是否是一个数字子字符串。

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

18 个答案:

答案 0 :(得分:232)

这是一种不依赖于尝试将字符串解析为数字的有限精度的方法:

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

请参阅+[NSCharacterSet decimalDigitCharacterSet]-[NSString rangeOfCharacterFromSet:]

答案 1 :(得分:31)

我建议使用NSNumberFormatter类中的numberFromString:方法,就好像数字无效一样,它将返回nil;否则,它会返回一个NSNumber。

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

答案 2 :(得分:10)

使用正则表达式(模式"^[0-9]+$")使用以下方法-validateString:withPattern:进行验证。

[self validateString:"12345" withPattern:"^[0-9]+$"];
  1. 如果考虑“123.123”
    • 使用模式"^[0-9]+(.{1}[0-9]+)?$"
  2. 如果恰好是4位数字,没有"."
    • 使用模式"^[0-9]{4}$"
  3. 如果数字编号没有".",且长度在2~5之间。
    • 使用模式"^[0-9]{2,5}$"
  4. 可以在the online web site中检查正则表达式。

    辅助功能如下。

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

    在操场上测试。

    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)
    

答案 3 :(得分:8)

您可以创建一个NSScanner并只扫描字符串:

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

查看NSScanner's documentation了解更多可供选择的方法。

答案 4 :(得分:6)

我认为检查给定字符串中的每个字符都是数字的最简单方法可能是:

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

如果要完全控制可接受的字符,请使用其他NSCharacterSet工厂方法。

答案 5 :(得分:6)

Swift 3解决方案,如果需要验证字符串只有数字:

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

答案 6 :(得分:5)

这个原始问题是关于Objective-C的,但它也是在Swift宣布之前发布的。所以,如果你是从谷歌来到这里并且正在寻找使用Swift的解决方案,那么你可以去:

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

答案 7 :(得分:4)

Swift 3解决方案可能就像:

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

答案 8 :(得分:4)

要清楚,这对于字符串中的整数起作用。

根据约翰的回答,提出了一个小助手类别:

<。>文件中的

@interface NSString (NumberChecking)

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

@end
<。>文件中的

#import "NSString+NumberChecking.h"

@implementation NSString (NumberChecking)

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

@end

用法:

#import "NSString+NumberChecking.h"

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

答案 9 :(得分:2)

John Calsbeek's answer几乎是正确的,但是省略了一些Unicode边缘情况。

对于每个documentation for decimalDigitCharacterSet,该集合包括所有按Unicode分类为Nd的字符。因此,他们的回答将被接受,其中包括:

  • (U + 0967 DEVANAGARI数字一)
  • (U + 1811蒙古文数字一位)
  • (U + 1D7D9数学双打击数字一位)

从某种意义上讲这是正确的-Nd中的每个字符都映射为十进制数字-几乎可以肯定,这不是提问者所期望的。在撰写本文时,共有610 code points categorized as Nd,其中只有十个是预期字符0(U + 0030)至9(U + 0039)。

要解决此问题,只需完全指定可接受的字符即可:

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

答案 10 :(得分:1)

又一个选择:

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

用法示例:

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

答案 11 :(得分:0)

Swift扩展名:

extension NSString {
func isNumString() -> Bool {
    let numbers = NSCharacterSet(charactersInString: "0123456789.").invertedSet
    let range = self.rangeOfCharacterFromSet(numbers).location
    if range == NSNotFound {
        return true
    }
    return false
}  }

答案 12 :(得分:0)

测试字符串是否为数字可能有帮助

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

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

答案 13 :(得分:0)

适用于Swift 3

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

答案 14 :(得分:0)

@John Calsbeek 的答案的扩展,以及 @Jeff 的说明 @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;
}

以下内容可以添加为 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;
}

答案 15 :(得分:0)

当您使用mixed languages中的数字(使用(或不使用)0-9数字格式)时,您将需要运行一个正则表达式来查找任何数字,接下来就是转换所有数字均为0-9格式(如果需要实际值):

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

答案 16 :(得分:0)

最简单,最可靠的方法是尝试将其转换为Double,如果结果为nil-无法将其转换为合法数字。

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]

文档中的更多信息: https://developer.apple.com/documentation/swift/double/2926277-init

答案 17 :(得分:0)

简单编写了字符串扩展名:

extension String {
    var isNumeric: Bool {
        return self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
    }
}