Finding out whether a string is numeric or not
How can we check if a string is made up of numbers only. I am taking out a substring from a string and want to check if it is a numeric substring or not.
NSString *newString = [myString substringWithRange:NSMakeRange(2,3)];
Here's one way that doesn't rely on the limited precision of attempting to parse the string as a number:
NSCharacterSet* notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
if ([newString rangeOfCharacterFromSet:notDigits].location == NSNotFound)
{
// newString consists only of the digits 0 through 9
}
See +[NSCharacterSet decimalDigitCharacterSet]
and -[NSString rangeOfCharacterFromSet:]
.
I'd suggest using the numberFromString:
method from the NSNumberFormatter class, as if the number is not valid, it will return nil; otherwise, it will return you an NSNumber.
NSNumberFormatter *nf = [[[NSNumberFormatter alloc] init] autorelease];
BOOL isDecimal = [nf numberFromString:newString] != nil;
Validate by regular expression, by pattern "^[0-9]+$"
, with following method -validateString:withPattern:
.
[self validateString:"12345" withPattern:"^[0-9]+$"];
- If "123.123" is considered
- With pattern
"^[0-9]+(.{1}[0-9]+)?$"
- With pattern
- If exactly 4 digit numbers, without
"."
.- With pattern
"^[0-9]{4}$"
.
- With pattern
- If digit numbers without
"."
, and the length is between 2 ~ 5.- With pattern
"^[0-9]{2,5}$"
.
- With pattern
- With minus sign:
"^-?\d+$"
The regular expression can be checked in the online web site.
The helper function is as following.
// 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:
Test in playground.
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)
You could create an NSScanner and simply scan the string:
NSDecimal decimalValue;
NSScanner *sc = [NSScanner scannerWithString:newString];
[sc scanDecimal:&decimalValue];
BOOL isDecimal = [sc isAtEnd];
Check out NSScanner's documentation for more methods to choose from.
I think the easiest way to check that every character within a given string is numeric is probably:
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");
}
Use one of the other NSCharacterSet factory methods if you want complete control over acceptable characters.