stringByAddingPercentEscapesUsingEncoding:
用這個方法進行轉義,每個漢字將轉成相應的unicode編碼對應的3個%形式踊谋,還會轉義一些特殊字符(比如空格會變成%20,#會變成%23,[會變成%5B等)却妨。該方法現在已經被廢棄耗帕,官方建議使用stringByAddingPercentEncodingWithAllowedCharacters:(下面會進行介紹)另玖。
stringByAddingPercentEscapesUsingEncoding:的用法:
NSString *queryWord = @"[q q&";
NSString *escapedString = [queryWord stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", escapedString);
打印結果為:%5Bq%20q&
可以發(fā)現空格和[都被轉義了佣赖,但是&沒有恰矩。
- (NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters的使用
這個方法是iOS7.0開始有的,這個方法會對字符串進行更徹底的轉義茵汰,需要傳遞一個參數:這個參數是一個字符集(NSCharacterSet?)枢里,這個字符集的作用是在進行轉義過程中孽鸡,不會對這個字符集中包含的字符進行轉義蹂午,使這個字符集中的字符保持原樣。
NSCharacterSet的介紹
NSCharacterSet類似一個字符串處理工具彬碱,除了在URL轉義中用到還可以用它來處理字符串豆胸。
NSCharacterSet的常用API:
/** 根據一個給定的字符串獲取一個NSCharacterSet對象 */
+ (NSCharacterSet*)characterSetWithCharactersInString:(NSString*)aString;
/** 相反字符串限制 ?*/
@property(readonly,copy)NSCharacterSet* invertedSet;
/** 常用快捷方法集合 (常用的,已滿足大多數需求) */
@property (readonly, class, copy) NSCharacterSet *whitespaceCharacterSet //空格
@property (readonly, class, copy) NSCharacterSet *whitespaceAndNewlineCharacterSet //空格和換行符
@property (readonly, class, copy) NSCharacterSet *decimalDigitCharacterSet //0-9的數字
@property (readonly, class, copy) NSCharacterSet *letterCharacterSet //所有字母 + lowercaseLetterCharacterSet//小寫字母
@property (readonly, class, copy) NSCharacterSet *uppercaseLetterCharacterSet //大寫字母
@property (readonly, class, copy) NSCharacterSet *alphanumericCharacterSet //所有數字和字母(大小寫不分)
@property (readonly, class, copy) NSCharacterSet *punctuationCharacterSet //標點符號
@property (readonly, class, copy) NSCharacterSet *newlineCharacterSet //換行
@property (class, readonly, copy) NSCharacterSet *URLQueryAllowedCharacterSet//URL中允許的字符的字符集巷疼。
上述屬性使用了class修飾晚胡,直接用[NSCharacterSet?whitespaceCharacterSet]就能獲取空格字符串集
例子一:使用NSCharacterSet轉義字符
轉義除了空格之外的所有字符
NSString *queryWord = @"[q q&";
NSCharacterSet *set = [NSCharacterSet whitespaceCharacterSet];
NSString *escapedString = [queryWord stringByAddingPercentEncodingWithAllowedCharacters:set];
NSLog(@"%@", escapedString);
打印結果為:%5B%71 %71%26可以發(fā)現除了空格之外的所有參數都被轉義,字母也被轉義了(這只是展示用法,實際參數轉義的時候還是要視情況定)估盘。
例子二:轉義除了空格和字母之外的字符
NSString *queryWord = @"[q q&";
NSMutableCharacterSet *letterSet = [NSMutableCharacterSet letterCharacterSet];
[letterSet addCharactersInString:@" "];
NSString *escapedString = [queryWord stringByAddingPercentEncodingWithAllowedCharacters:letterSet];
NSLog(@"%@", escapedString);
打印結果為:%5Bq q%26
例子三:使用NSCharacterSet處理字符串
需求:把字符串中的數字和字符串分別截取出來瓷患,分成兩個字符串
NSString *originalStr = @"qssq21233fd23j49fr034";
NSCharacterSet *numCharacterSet = [NSCharacterSet decimalDigitCharacterSet];//創(chuàng)建數字的字符串集
NSArray *letterArray = [originalStr componentsSeparatedByCharactersInSet:numCharacterSet];//把不在字符集中的字符分離成數組
NSString *letterStr = [letterArray componentsJoinedByString:@""];//把字符數組以空字符串拼成一個字符串
NSArray *numArray = [originalStr componentsSeparatedByCharactersInSet:[numCharacterSet invertedSet]];
NSString *numStr = [numArray componentsJoinedByString:@""];
NSLog(@"字母字符串:%@", letterStr);
NSLog(@"數字字符串:%@", numStr);
打印結果:字母字符串:qssqfdjfr
? ?????????????????數字字符串:212332349034
AFNetworking中轉義字符串的源碼解析
NSString * AFPercentEscapedStringFromString(NSString *string) {
? ? //定義兩個字符串,這兩個字符串中的字符還是需要轉義的
? ? static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
? ? static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
????//獲取URL中允許的字符的字符集。
? ? NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
????//在URL中允許的字符的字符集中移除上面需要轉義的字符集
? ? [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
// FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028
? ? // return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
????//以50個字符為單位截取字符串
? ? static NSUInteger const batchSize = 50;
? ? NSUInteger index = 0;
? ? NSMutableString *escaped = @"".mutableCopy;
????//最后一次字符的位置比字符串的長度星餐住()即未轉義完時繼續(xù)轉義
? ? while (index < string.length) {
????????//獲取剩余字符串長度和截取單位50的最小值擅编,剩余長度大于50,先截取50個字符
? ? ? ? NSUInteger length = MIN(string.length - index, batchSize);
? ? ? ? NSRange range = NSMakeRange(index, length);
? ? ?????//像表情(????????),一個表情有多個字符箫踩,這個方法是為了防止表情或者漢字被截斷
? ? ? ? range = [string rangeOfComposedCharacterSequencesForRange:range];
? ? ? ? NSString *substring = [string substringWithRange:range];
????????//轉義allowedCharacterSet字符集外的字符
? ? ? ? NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
????????//把轉義后的字符拼接到準備的可變字符串
? ? ? ? [escaped appendString:encoded];
? ? ? ? index += range.length;
? ? }
return escaped;
}