Как проверить, содержит ли NSString числовое значение? - PullRequest
29 голосов
/ 11 июля 2011

У меня есть строка, которая генерируется по формуле, однако я хочу использовать строку только до тех пор, пока все ее символы числовые, если нет, то я хочу сделать что-то другое, например, отобразить сообщение об ошибке. 1001 *

Я осматривался, но мне трудно найти что-то, что будет соответствовать тому, что я хочу сделать. Я посмотрел на NSScanner, но я не уверен, что он проверяет всю строку, а затем я не совсем уверен, как проверить, являются ли эти символы числовыми

- (void)isNumeric:(NSString *)code{

    NSScanner *ns = [NSScanner scannerWithString:code];
    if ( [ns scanFloat:NULL] ) //what can I use instead of NULL?
    {
        NSLog(@"INSIDE IF");
    }
    else {
    NSLog(@"OUTSIDE IF");
    }
}

Так что после нескольких часов поиска я наткнулся на реализацию, которая точно соответствует тому, что я ищу.

, поэтому, если вы хотите проверить, являются ли они буквенно-цифровыми символами в вашей NSString, это работает здесь

-(bool) isNumeric:(NSString*) hexText
{

    NSNumberFormatter* numberFormatter = [[[NSNumberFormatter alloc] init] autorelease];

    NSNumber* number = [numberFormatter numberFromString:hexText];

    if (number != nil) {
        NSLog(@"%@ is numeric", hexText);
        //do some stuff here      
        return true;
    }

    NSLog(@"%@ is not numeric", hexText);
    //or do some more stuff here
    return false;
}

надеюсь, это поможет.

Ответы [ 7 ]

51 голосов
/ 09 декабря 2011

Примерно так будет работать:

@interface NSString (usefull_stuff)
- (BOOL) isAllDigits;
@end

@implementation NSString (usefull_stuff)

- (BOOL) isAllDigits
{
    NSCharacterSet* nonNumbers = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
    NSRange r = [self rangeOfCharacterFromSet: nonNumbers];
    return r.location == NSNotFound && self.length > 0;
}

@end

, тогда просто используйте его так:

NSString* hasOtherStuff = @"234 other stuff";
NSString* digitsOnly = @"123345999996665003030303030";

BOOL b1 = [hasOtherStuff isAllDigits];
BOOL b2 = [digitsOnly isAllDigits];

Вам не нужно заключать эту функциональность в расширение для частной категории, как это, но это, безусловно, облегчает повторное использование ..

Мне нравится это решение лучше, чем другие, так как оно никогда не переполняет некоторые int / float, которые сканируются через NSScanner - количество цифр может быть практически любымдлина.

15 голосов
/ 11 июля 2011

Рассмотрим NSString integerValue - возвращается NSInteger. Однако он будет принимать некоторые строки, которые не являются полностью числовыми, и не предоставляет механизм для определения строк, которые не являются числовыми вообще. Это может или не может быть приемлемым.

Например, " 13 " -> 13, "42foo" -> 42 и "helloworld" -> 0.

Удачного кодирования.


Теперь, поскольку вышеприведенное было своего рода касательной к вопросу, см. Определение, является ли строка числовой . Код взят по ссылке, с добавлением комментариев:

BOOL isNumeric(NSString *s)
{
   NSScanner *sc = [NSScanner scannerWithString: s];
   // We can pass NULL because we don't actually need the value to test
   // for if the string is numeric. This is allowable.
   if ( [sc scanFloat:NULL] )
   {
      // Ensure nothing left in scanner so that "42foo" is not accepted.
      // ("42" would be consumed by scanFloat above leaving "foo".)
      return [sc isAtEnd];
   }
   // Couldn't even scan a float :(
   return NO;
}

Выше работает только с scanFloat - например, нет scanInt - потому что диапазон с плавающей запятой намного больше , чем диапазон целого числа (даже 64-разрядного целого).

Эта функция проверяет «полностью числовые» значения и принимает "42" и "0.13E2", но отклоняет " 13 ", "42foo" и "helloworld".

8 голосов
/ 11 июля 2011

Как это:

- (void)isNumeric:(NSString *)code{

    NSScanner *ns = [NSScanner scannerWithString:code];
    float the_value;
    if ( [ns scanFloat:&the_value] )
    {
        NSLog(@"INSIDE IF");
        // do something with `the_value` if you like
    }
    else {
    NSLog(@"OUTSIDE IF");
    }
}
7 голосов
/ 08 июля 2014

Это очень просто.

+ (BOOL)isStringNumeric:(NSString *)text
{
    NSCharacterSet *alphaNums = [NSCharacterSet decimalDigitCharacterSet];
    NSCharacterSet *inStringSet = [NSCharacterSet characterSetWithCharactersInString:text];        
    return [alphaNums isSupersetOfSet:inStringSet];
}
2 голосов
/ 05 ноября 2014

Столкнулся с такой же проблемой в Swift.
В Swift вы должны использовать этот код в соответствии с ответом TomSwift:

func isAllDigits(str: String) -> Bool {

    let nonNumbers = NSCharacterSet.decimalDigitCharacterSet()

    if let range = str.rangeOfCharacterFromSet(nonNumbers) {
        return true
    }
    else {
        return false
    }
}

PS Также вы можете использовать другие NSCharacterSets или их комбинации для проверки вашей строки!

0 голосов
/ 27 января 2018

С. Джонс ответил неверно.Если вы используете средство форматирования, вы рискуете, что Apple в какой-то момент изменит свою кодовую базу и заставит средство форматирования выпустить частичный результат.Том тоже не прав.Если вы используете метод rangeOfCharacterFromSet и проверяете наличие NSNotFound, он зарегистрирует значение true, если строка содержит хотя бы одно число.Аналогичным образом, другие ответы в этой теме предлагают использовать метод целочисленных значений.Это также неправильно, потому что он зарегистрирует true, если в строке присутствует хотя бы одно целое число.ОП запросил ответ, который гарантирует, что строка whole является числовой.Попробуйте это:

NSCharacterSet *searchSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];

Том был прав насчет этой части.Этот шаг дает вам нечисловые строковые символы.Но затем мы делаем это:

NSString *trimmedString = [string stringByTrimmingCharactersInSet:searchSet];

return (string.length == trimmedString.length);

Перевернутый набор символов Тома может TRIM строку.Таким образом, мы можем использовать этот метод обрезки, чтобы проверить, существуют ли какие-либо не числа в строке, сравнивая их длины.

0 голосов
/ 08 июля 2014

Для простых чисел, таких как «12234» или «231231.23123», ответ может быть простым.

Существует закон преобразования для чисел int: когда строка с целым числом преобразуется в число int (или long), а затемснова, преобразует его обратно в другую строку, эти строки будут равны.

В Objective C это будет выглядеть следующим образом:

NSString *numStr=@"1234",*num2Str=nil;
num2Str=[NSString stringWithFormat:@"%lld",numStr.longlongValue];

if([numStr isEqualToString: num2Str]) NSLog(@"numStr is an integer number!");

Используя этот закон преобразования, мы можем создать решение
дляобнаружить double или long числа:

NSString *numStr=@"12134.343"
NSArray *numList=[numStr componentsSeparatedByString:@"."];

if([[NSString stringWithFormat:@"%lld", numStr.longLongValue] isEqualToString:numStr]) NSLog(@"numStr is an integer number"); 
else 
if( numList.count==2 &&
               [[NSString stringWithFormat:@"%lld",((NSString*)numList[0]).longLongValue] isEqualToString:(NSString*)numList[0]] &&
               [[NSString stringWithFormat:@"%lld",((NSString*)numList[1]).longLongValue] isEqualToString:(NSString*)numList[1]] )
            NSLog(@"numStr is a double number");
else 
NSLog(@"numStr is not a number");

Я не скопировал приведенный выше код из своего рабочего кода, поэтому могут быть некоторые ошибки, но я думаю, что главное ясно.Конечно, это решение не работает с числами типа «1E100», а также не учитывает размер целой и дробной части.Используя закон, описанный выше, вы можете выполнять любое обнаружение номера.

...