NSScanner使用详解

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;
  • string就是初始话时候输入的目标字符串,而且是只读的
  • scanLocation是scaner当前的扫描位置,初始化完成后默认是0,这个值会随着扫描方法的调用而变化(往前或不变)
  • chatactersToBeSkipper是想要跳过的字符串集合,当scanner扫描这个集合中的元素时候,它就会跳过去。例如有个字符串是@“111A2222”,如果要把这个字符串中的数字给扫描出来,那个把A作为chatactersToBeSkipper的集合,那么扫描会跳过A,最后会得出111和2222这两个数字
  • caseSensitive 是否大小写敏感,YES的话scanner会区分大小写,NO是不区分,默认是NO
  • locale 本地化,是用在小数点分隔符上。一般都不用指定
  • atEnd YES代表整个字符串已经扫描完毕,NO则表示还没扫完。如果整个字符串都是由chatactersToBeSkipper的元素组成,则返回YES

扫描规则

  • scanner的每个扫描方法都返回是否成功,如果返回成功则scanLocation会往前移动相对应的位置(就是扫出来的内容的长度),如果返回NO则scanLocation不会变化。例如对@“A111A2222”进行数字的扫描,因为一开始scanLocation是从0开始,如果进行以下的数字扫描操作:
        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;
     }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,214评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,307评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,543评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,221评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,224评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,007评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,313评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,956评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,441评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,925评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,018评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,685评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,234评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,240评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,464评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,467评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,762评论 2 345

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,599评论 18 139
  • NSScanner是一个类,用于在字符串中扫描指定的字符,尤其是把它们翻译/转换为数字和别的字符串。可以在创建NS...
    践行者阅读 1,893评论 0 2
  • 转义字符 在字符表中有两大类字符集,一类是Control Character,一类是Printable Chara...
    狮_子歌歌阅读 8,261评论 0 7
  • NSScanner类是一个类簇的抽象父类,该类簇为一个从NSString对象扫描值的对象提供了程序接口。 NSSc...
    以技术之名阅读 5,984评论 4 39
  • Linux版本 Linux主流产品 root环境~用户的家目录管理员环境.png linux命令形式 命令和参数之...
    养码哥阅读 149评论 0 1