Answers:
这是一种不依赖于尝试将字符串解析为数字的有限精度的方法:
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
请参阅+[NSCharacterSet decimalDigitCharacterSet]
和-[NSString rangeOfCharacterFromSet:]
。
[[NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet]]
invertedSet
返回的类包装了它创建的表单集,并为所有查询返回相反的值。但是我不确定。
我建议使用NSNumberFormatter类中的numberFromString:
方法,好像该数字无效,它将返回nil。否则,它将返回一个NSNumber。
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
NO
您的字符串。同样值得一提的是:它们还会返回YES
用空格填充的数字。顺便说一句,我只是在您的答案中添加了一些实际的代码片段,希望您不要介意。
"^[0-9]+$"
使用以下方法通过正则表达式,模式进行验证-validateString:withPattern:
。
[self validateString:"12345" withPattern:"^[0-9]+$"];
"^[0-9]+(.{1}[0-9]+)?$"
"."
。
"^[0-9]{4}$"
。"."
,长度在2到5之间。
"^[0-9]{2,5}$"
。"^-?\d+$"
可以在在线网站上检查正则表达式。
辅助功能如下。
// 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;
}
在操场上测试。
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 }
我遇到了错误Playground execution aborted: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
return matchRange.location != NSNotFound;
^-?\d+$
,我在以下网站上进行了验证:regex101.com
您可以创建一个NSScanner并简单地扫描字符串:
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
请查看NSScanner的文档,以获取更多可供选择的方法。
isAtEnd
。
我认为检查给定字符串中每个字符是否为数字的最简单方法可能是:
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工厂方法之一。
这个最初的问题是关于Objective-C的,但是它也在Swift宣布之前就发布了。因此,如果您来自Google,并且正在寻找使用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.")
}
如果需要验证字符串仅包含数字,则使用Swift 3解决方案:
CharacterSet.decimalDigits.isSuperset(of: CharacterSet(charactersIn: myString))
.inverted
动作。
需要明确的是,此函数用于字符串中的整数。
根据上述约翰的回答,这是一个小帮手类别:
在.h文件中
@interface NSString (NumberChecking)
+(bool)isNumber:(NSString *)string;
@end
在.m文件中
#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");
}
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)
}
}
}
John Calsbeek的答案几乎是正确的,但是省略了一些Unicode边缘情况。
根据的文档decimalDigitCharacterSet
,该集合包括按Unicode分类为的所有字符Nd
。因此,他们的回答将被接受,其中包括:
१
(U + 0967 DEVANAGARI数字一)᠑
(U + 1811蒙古文数字一位)𝟙
(U + 1D7D9数学双打击数字1)从某种意义上讲这是正确的-每个字符Nd
都映射到一个十进制数字-几乎可以肯定,这不是提问者所期望的。截至撰写本文时,共有610个代码点,分类为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
}
另一个选择:
- (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]+$"];
@John Calsbeek的答案的扩展 ,以及@Jeff和@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;
}
可以添加以下内容作为类别方法 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;
}
测试字符串是否为数字可能会有帮助
int i = [@"12.3" rangeOfCharacterFromSet: [ [NSCharacterSet characterSetWithCharactersInString:@"0123456789."] invertedSet] ].location;
if (i == NSNotFound) {
//is a number
}
迅速扩展:
extension NSString {
func isNumString() -> Bool {
let numbers = NSCharacterSet(charactersInString: "0123456789.").invertedSet
let range = self.rangeOfCharacterFromSet(numbers).location
if range == NSNotFound {
return true
}
return false
} }
对于Swift 3
var onlyDigits: CharacterSet = CharacterSet.decimalDigits.inverted
if testString.rangeOfCharacter(from: onlyDigits) == nil {
// String only consist digits 0-9
}
如果您使用的是混合语言的数字(使用(或不使用)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
}
最简单,最可靠的方法是尝试将as强制转换为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
简单写了字符串扩展名:
extension String {
var isNumeric: Bool {
return self.rangeOfCharacter(from: CharacterSet.decimalDigits.inverted) == nil
}
}
.
字符