NSFoundationiOS相关

NSScanner使用详解

2017-03-19  本文已影响0人  雷侯塞利

NSScanner是一个类簇,它管理着很多可以从NSString中扫描出数字值或字符值的私有类。通常拿NSScanner对字符串进行比较简单的扫描来获取指定内容(数字值或字符值)。

初始化

- (instancetype)initWithString:(NSString *)string 
+ (instancetype)scannerWithString:(NSString *)string;
+ (id)localizedScannerWithString:(NSString *)string;

把想要扫描的字符串作为NSScaner的初始化参数,后续的扫描操作都是对这个string进行操作

属性

@property (readonly, copy) NSString *string;
@property NSUInteger scanLocation;
@property (nullable, copy) NSCharacterSet *charactersToBeSkipped;
@property BOOL caseSensitive;
@property (nullable, retain) id locale;
@property (getter=isAtEnd, readonly) BOOL atEnd;

扫描规则

        int value;
        while (![scanner isAtEnd]) {
            [scanner scanInt:&value];
            NSLog(@"%d, %d",value,scanner.scanLocation);
        }

则会产生死循环,因为第一个是字母,扫描数字不成功,scanLocation一直保持0,然后atEnd都是NO,所以while语句一直执行。所以这个可以把A或者整个字母/空格集合放在chatactersToBeSkipper集合,这样scanner就可以自动跳过字母去扫描数字

扫描方法

扫描数字类型

- (BOOL)scanInt:(nullable int *)result;
- (BOOL)scanInteger:(nullable NSInteger *)result NS_AVAILABLE(10_5, 2_0);
- (BOOL)scanLongLong:(nullable long long *)result;
- (BOOL)scanUnsignedLongLong:(nullable unsigned long long *)result NS_AVAILABLE(10_9, 7_0);
- (BOOL)scanFloat:(nullable float *)result;
- (BOOL)scanDouble:(nullable double *)result;
- (BOOL)scanHexInt:(nullable unsigned *)result;                                          // Optionally prefixed with "0x" or "0X"
- (BOOL)scanHexLongLong:(nullable unsigned long long *)result NS_AVAILABLE(10_5, 2_0);   // Optionally prefixed with "0x" or "0X"
- (BOOL)scanHexFloat:(nullable float *)result NS_AVAILABLE(10_5, 2_0);                   // Corresponding to %a or %A formatting. Requires "0x" or "0X" prefix.
- (BOOL)scanHexDouble:(nullable double *)result NS_AVAILABLE(10_5, 2_0);                 // Corresponding to %a or %A formatting. Requires "0x" or "0X" prefix.

当执行上面的扫描方法时,当前的扫描位置的字符必须是数字的开头(扫描HEX则是要0x开头),否则扫描不成功

扫描指定字符串或字符集合

- (BOOL)scanString:(NSString *)string intoString:(NSString * _Nullable * _Nullable)result;
- (BOOL)scanCharactersFromSet:(NSCharacterSet *)set intoString:(NSString * _Nullable * _Nullable)result;

scanString是指扫描指定的字符串,scanCharacterFromSet是指扫描指定字符集合元素组合成的字符串,intoString指的是扫描出来的结果。例如我要扫描@"AABBTCCDD"中的A\B\C\D组合成的内容,T是不想要的字符,则

NSString *test = @"AABBTCCDD";
NSScanner *scanner = [NSScanner scannerWithString:test];
NSCharacterSet *set = [NSCharacterSet characterSetWithCharactersInString:@"T"]; scanner.charactersToBeSkipped = set;   
NSCharacterSet *set2 = [NSCharacterSet characterSetWithCharactersInString:@"ABCD"];
NSString *str;
while (![scanner isAtEnd]) {
  [scanner scanCharactersFromSet:set2 intoString:&str];
  NSLog(@"%@",str);
  //scanner[1343:108886] AABB
  //scanner[1343:108886] CCDD
 }

扫描字符一直到出现指定的字符串和字符集合内容

- (BOOL)scanUpToString:(NSString *)string intoString:(NSString * _Nullable * _Nullable)result;
- (BOOL)scanUpToCharactersFromSet:(NSCharacterSet *)set intoString:(NSString * _Nullable * _Nullable)result;

scanner会一直往前扫描指定遇到指定的字符串或由指定字符集合内容组成的字符串时才会停下来,途中扫描的字符串内容会从introStrign参数中返回

实战例子

通过扫描#FF0000或者(235,235,235)字符串来获的对应的颜色

- (BOOL)scanColor:(UIColor **)out
{
     return [self scanHexColorIntoColor:out] || [self scanTupleColorIntoColor:out];
}
 
//扫描设置#ff0000这样的
- (BOOL)scanHexColorIntoColor:(UIColor **)out
{
     NSCharacterSet *hexadecimalCharacterSet =
          [NSCharacterSet characterSetWithCharactersInString:@"0123456789abcdefABCDEF"];
     NSString *colorString = NULL;
     if ([self.scanner scanString:@"#" intoString:NULL] &&
          [self.scanner scanCharactersFromSet:hexadecimalCharacterSet
          intoString:&colorString] &&
          colorString.length == 6) {
          *out = [UIColor colorWithHexString:colorString];
          return YES;
     }
     return NO;
}
 
- (BOOL)scanTupleColorIntoColor:(UIColor **)out
{
     NSInteger red, green, blue = 0;
     BOOL didScan = [self.scanner scanString:@"(" intoString:NULL] &&
          [self.scanner scanInteger:&red] &&
          [self.scanner scanString:@"," intoString:NULL] &&
          [self.scanner scanInteger:&green] &&
          [self.scanner scanString:@"," intoString:NULL] &&
          [self.scanner scanInteger:&blue] &&
          [self.scanner scanString:@")" intoString:NULL];
     if (didScan) {
          *out = [UIColor colorWithRed:(CGFloat)red/255.
               green:(CGFloat)green/255.
               blue:(CGFloat)blue/255.
               alpha:1];
          return YES;
     } else {
          return NO;
     }
}
上一篇下一篇

猜你喜欢

热点阅读