NSScanner是一個(gè)類簇,它管理著很多可以從NSString中掃描出數(shù)字值或字符值的私有類。通常拿NSScanner對字符串進(jìn)行比較簡單的掃描來獲取指定內(nèi)容(數(shù)字值或字符值)。
初始化
- (instancetype)initWithString:(NSString *)string
+ (instancetype)scannerWithString:(NSString *)string;
+ (id)localizedScannerWithString:(NSString *)string;
把想要掃描的字符串作為NSScaner的初始化參數(shù),后續(xù)的掃描操作都是對這個(gè)string進(jìn)行操作
屬性
@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就是初始話時(shí)候輸入的目標(biāo)字符串,而且是只讀的
- scanLocation是scaner當(dāng)前的掃描位置,初始化完成后默認(rèn)是0,這個(gè)值會(huì)隨著掃描方法的調(diào)用而變化(往前或不變)
- chatactersToBeSkipper是想要跳過的字符串集合,當(dāng)scanner掃描這個(gè)集合中的元素時(shí)候,它就會(huì)跳過去。例如有個(gè)字符串是@“111A2222”,如果要把這個(gè)字符串中的數(shù)字給掃描出來,那個(gè)把A作為chatactersToBeSkipper的集合,那么掃描會(huì)跳過A,最后會(huì)得出111和2222這兩個(gè)數(shù)字
- caseSensitive 是否大小寫敏感,YES的話scanner會(huì)區(qū)分大小寫,NO是不區(qū)分,默認(rèn)是NO
- locale 本地化,是用在小數(shù)點(diǎn)分隔符上。一般都不用指定
- atEnd YES代表整個(gè)字符串已經(jīng)掃描完畢,NO則表示還沒掃完。如果整個(gè)字符串都是由chatactersToBeSkipper的元素組成,則返回YES
掃描規(guī)則
- scanner的每個(gè)掃描方法都返回是否成功,如果返回成功則scanLocation會(huì)往前移動(dòng)相對應(yīng)的位置(就是掃出來的內(nèi)容的長度),如果返回NO則scanLocation不會(huì)變化。例如對@“A111A2222”進(jìn)行數(shù)字的掃描,因?yàn)橐婚_始scanLocation是從0開始,如果進(jìn)行以下的數(shù)字掃描操作:
int value;
while (![scanner isAtEnd]) {
[scanner scanInt:&value];
NSLog(@"%d, %d",value,scanner.scanLocation);
}
則會(huì)產(chǎn)生死循環(huán),因?yàn)榈谝粋€(gè)是字母,掃描數(shù)字不成功,scanLocation一直保持0,然后atEnd都是NO,所以while語句一直執(zhí)行。所以這個(gè)可以把A或者整個(gè)字母/空格集合放在chatactersToBeSkipper集合,這樣scanner就可以自動(dòng)跳過字母去掃描數(shù)字
- 掃描操作從上次掃描的位置開始,并且繼續(xù)往后掃描直到指定的內(nèi)容出現(xiàn)為止(如果有的話)。
掃描方法
掃描數(shù)字類型
- (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.
當(dāng)執(zhí)行上面的掃描方法時(shí),當(dāng)前的掃描位置的字符必須是數(shù)字的開頭(掃描HEX則是要0x開頭),否則掃描不成功
掃描指定字符串或字符集合
- (BOOL)scanString:(NSString *)string intoString:(NSString * _Nullable * _Nullable)result;
- (BOOL)scanCharactersFromSet:(NSCharacterSet *)set intoString:(NSString * _Nullable * _Nullable)result;
scanString是指掃描指定的字符串,scanCharacterFromSet是指掃描指定字符集合元素組合成的字符串,intoString指的是掃描出來的結(jié)果。例如我要掃描@"AABBTCCDD"中的A\B\C\D組合成的內(nèi)容,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
}
掃描字符一直到出現(xiàn)指定的字符串和字符集合內(nèi)容
- (BOOL)scanUpToString:(NSString *)string intoString:(NSString * _Nullable * _Nullable)result;
- (BOOL)scanUpToCharactersFromSet:(NSCharacterSet *)set intoString:(NSString * _Nullable * _Nullable)result;
scanner會(huì)一直往前掃描指定遇到指定的字符串或由指定字符集合內(nèi)容組成的字符串時(shí)才會(huì)停下來,途中掃描的字符串內(nèi)容會(huì)從introStrign參數(shù)中返回
實(shí)戰(zhàn)例子
通過掃描#FF0000或者(235,235,235)字符串來獲的對應(yīng)的顏色
- (BOOL)scanColor:(UIColor **)out
{
return [self scanHexColorIntoColor:out] || [self scanTupleColorIntoColor:out];
}
//掃描設(shè)置#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;
}
}