Цель-C: найти числа в строке
У меня есть строка, которая содержит слова, а также число. Как извлечь это число из строки?
NSString *str = @"This is my string. #1234";
Я хотел бы иметь возможность удалить 1234 как int. Строка будет иметь разные числа и слова каждый раз, когда я ее ищу.
идеи?
7 ответов
здесь NSScanner решение:
// Input
NSString *originalString = @"This is my string. #1234";
// Intermediate
NSString *numberString;
NSScanner *scanner = [NSScanner scannerWithString:originalString];
NSCharacterSet *numbers = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
// Throw away characters before the first number.
[scanner scanUpToCharactersFromSet:numbers intoString:NULL];
// Collect numbers.
[scanner scanCharactersFromSet:numbers intoString:&numberString];
// Result.
int number = [numberString integerValue];
(некоторые из многих) допущений, сделанных здесь:
- цифры номера 0-9, никакой знак, никакая десятичная точка, никакие тысяча разделители, ЕТК. При необходимости можно добавить символы знака в NSCharacterSet.
- нет никаких цифр в другом месте строки, или если они есть, они после номер, который вы хотите извлечь.
- номер не переполнит
int
.
в качестве альтернативы вы можете сканировать прямо на int
:
[scanner scanUpToCharactersFromSet:numbers intoString:NULL];
int number;
[scanner scanInt:&number];
если #
отмечает начало числа в строке, вы можете найти его с помощью:
[scanner scanUpToString:@"#" intoString:NULL];
[scanner setScanLocation:[scanner scanLocation] + 1];
// Now scan for int as before.
самостоятельного решения:
+ (NSString *)extractNumberFromText:(NSString *)text
{
NSCharacterSet *nonDigitCharacterSet = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
return [[text componentsSeparatedByCharactersInSet:nonDigitCharacterSet] componentsJoinedByString:@""];
}
обрабатывает следующие случаи:
- @"1234" → @"1234"
- @"001234" → @"001234"
- @ "ведущий текст удален 001234" → @ "001234"
- @ "001234 конечный текст удаляется" → @ "001234"
- @"a0b0c1d2e3f4" → @"001234"
надеюсь, что это помогает!
попробовать ответ из переполнения стека для хорошего куска кода C, который сделает трюк:
for (int i=0; i<[str length]; i++) {
if (isdigit([str characterAtIndex:i])) {
[strippedString appendFormat:@"%c",[str characterAtIndex:i]];
}
}
вы можете использовать класс NSRegularExpression, доступный с iOS SDK 4.
Ниже приведен простой код для извлечения целых чисел ( " \d+" шаблон регулярного выражения) :
- (NSArray*) getIntNumbersFromString: (NSString*) string {
NSMutableArray* numberArray = [NSMutableArray new];
NSString* regexPattern = @"\d+";
NSRegularExpression* regex = [[NSRegularExpression alloc] initWithPattern:regexPattern options:0 error:nil];
NSArray* matches = [regex matchesInString:string options:0 range:NSMakeRange(0, string.length)];
for( NSTextCheckingResult* match in matches) {
NSString* strNumber = [string substringWithRange:match.range];
[numberArray addObject:[NSNumber numberWithInt:strNumber.intValue]];
}
return numberArray;
}
безусловно, лучшее решение! Я думаю, что регулярное выражение было бы лучше, но я вроде как sux ;-) это фильтрует все числа и объединяет их вместе, создавая новую строку. Если вы хотите разделить несколько чисел, измените его немного. И помните, что когда вы используете это внутри большого цикла, это стоит производительности!
NSString *str= @"bla bla bla #123 bla bla 789";
NSMutableString *newStr = [[NSMutableString alloc] init];;
int j = [str length];
for (int i=0; i<j; i++) {
if ([str characterAtIndex:i] >=48 && [str characterAtIndex:i] <=59) {
[newStr appendFormat:@"%c",[str characterAtIndex:i]];
}
}
NSLog(@"%@ as int:%i", newStr, [newStr intValue]);
NSPredicate - класс Cocoa для синтаксического анализа строки с помощью регулярное выражение ICU.
Swift расширение для получения номера из строки
extension NSString {
func getNumFromString() -> String? {
var numberString: NSString?
let thisScanner = NSScanner(string: self as String)
let numbers = NSCharacterSet(charactersInString: "0123456789")
thisScanner.scanUpToCharactersFromSet(numbers, intoString: nil)
thisScanner.scanCharactersFromSet(numbers, intoString: &numberString)
return numberString as? String;
}
}