Подтвердить что ты не робот

Выяснение, является ли строка числовой или нет

Как проверить, содержит ли строка только цифры. Я вынимаю подстроку из строки и хочу проверить, является ли она числовой подстрокой или нет.

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

Ответ 1

Здесь один из способов, который не полагается на ограниченную точность попытки разобрать строку как число:

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

См. +[NSCharacterSet decimalDigitCharacterSet] и -[NSString rangeOfCharacterFromSet:].

Ответ 2

Я бы предложил использовать метод numberFromString: из класса NSNumberFormatter, как если бы это число недействительно, оно вернется ноль; в противном случае он вернет вам NSNumber.

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

Ответ 3

Проверяется регулярным выражением, шаблоном "^[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}$".

Регулярное выражение можно проверить на веб-сайте онлайн.

Вспомогательная функция заключается в следующем.

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

Ответ 4

Вы можете создать NSScanner и просто просмотреть строку:

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

Ознакомьтесь с документацией NSScanner для получения дополнительных методов.

Ответ 5

Я думаю, что самый простой способ проверить, что каждый символ в данной строке является числовым, вероятно:

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 factory, если вы хотите получить полный контроль над допустимыми символами.

Ответ 6

Решение Swift 3, если необходимо проверить, что строка содержит только цифры:

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

Ответ 7

Этот оригинальный вопрос касался 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.")
}

Ответ 8

чтобы быть ясным, эти функции для целых чисел в строках.

heres немного вспомогательная категория, основанная на ответе Джона выше:

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

Ответ 9

Решение 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)
        }
    }
}

Ответ 10

Ответ Джона Калсбека почти правильный, но в нем отсутствуют некоторые крайние случаи Unicode.

Согласно документации для decimalDigitCharacterSet, этот набор включает в себя все символы, классифицированные Unicode как Nd. Таким образом, их ответ примет, среди прочего:

  • + 0967 Деванагари СИМВОЛЬНЫЙ ONE)
  • U (U + 1811 ОДИН)
  • 𝟙 (U + 1D7D9 МАТЕМАТИЧЕСКИЙ ЦИФРОВОЙ ДВОЙНОЙ СТРОК)

Хотя в некотором смысле это правильно - каждый символ в 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
}

Ответ 11

Еще один вариант:

- (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]+$"];

Ответ 12

Проверить, является ли строка числом, может быть полезным

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

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

Ответ 13

Быстрое расширение:

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

Ответ 14

Для Swift 3

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

Ответ 15

Расширение ответа @John Calsbeek и пояснения комментариев @Jeff и @gyratory circc.

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

Ответ 16

Если у вас есть цифры из смешанных языков, которые используют (или не используют) форматы 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
}

Ответ 17

Самый простой и надежный способ - использовать 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