在Object-c中,字符串處理通常使用NSString,NSMutableString這兩個類,前者用於定長字符串,後者用於可變長度字符串的操作。盡量其提供的方法很豐富,但一用起來後就讓人感到很難受,比如其超長的方法名稱(如stringByReplacingPercentEscapesUsingEncoding),再加上嵌套“[]”式的調用方式,讓人很快就會產生"[]"匹配綜合症。
即使xcode提供了自動配對“[]”號的功能,但一閱讀起源代碼後依舊讓人心生厭惡。給人一種“強迫打字綜合症”的感覺。所以我在NSMutableString基礎上用C++進行了封裝,特別是對於一些常用方法的使用,在使用時會非常方便,與C#沒太大差別。
首先看一下String類的源碼(說明:因為C++中有std::string這個類,為了與其區別,這裡使用了首字母大寫)。
- #import "RegexKitLite.h"
-
- #define RELEASE_SAFELY(__POINTER) { [__POINTER release]; __POINTER = nil; }
-
- class String {
- private:
-
- NSMutableString *temp;
-
- static inline NSMutableString* ToMutableString(NSString *str){
- return [[NSMutableString stringWithString:(NSString *)str] autorelease];
- }
-
- public :
- String(){
- temp = ToMutableString(@"");
- }
-
- String(NSString *str){
- temp = ToMutableString(str);
- }
-
- String(int value){
- temp = ToMutableString([NSString stringWithFormat:@"%d", value]);
- }
-
- String(float value){
- temp = ToMutableString([NSString stringWithFormat:@"%f", value]);
- }
-
- String(std::string str){
- temp = ToMutableString(toNSString(str));
- }
-
- String(const char* str){
- temp = ToMutableString(toNSString(str));
- }
-
- ~String(){
- RELEASE_SAFELY(temp);
- }
-
- NSString * toString(){
- return temp;
- }
-
- const std::string toStdString(){
- return [temp UTF8String];
- }
-
- NSString * toLower(){
- return [temp lowercaseString];
- }
-
- NSString* toUpper(){
- return [temp uppercaseString];
- }
-
- int length(){
- return temp.length;
- }
-
- bool contains(NSString *search){
- return [temp rangeOfString:search].location != NSNotFound;
- }
-
- //不考慮大小寫
- static BOOL stringEquals(NSString* str1, NSString* str2)
- {
- if ( str1 == nil || str2 == nil ) {
- return NO;
- }
- return [str1 compare:str2 options:NSCaseInsensitiveSearch] == NSOrderedSame;
- }
-
- //區分大小寫
- static BOOL caseEquals(NSString* str1, NSString* str2)
- {
- return (str1 == nil || str2 == nil) ? NO : [str1 isEqualToString:str2];
- }
-
- bool operator==( NSString *str)
- {
- return caseEquals(this->toString(), str);
- }
-
- bool operator==( String *str)
- {
- return caseEquals(this->toString(), str->toString());
- }
-
- //區分大小寫
- BOOL startWith(NSString *prefix){
- if ( temp != nil && prefix != nil ){
- if ( prefix.length > temp.length ) {
- return NO;
- }
- if ([temp hasPrefix:prefix]){
- return YES;
- }
- }
- return NO;
- }
-
- //區分大小寫
- BOOL endWith(NSString* suffix){
- if ( temp != nil && suffix != nil ){
- if ( [suffix length] > [temp length] ) {
- return NO;
- }
- if ([temp hasSuffix:suffix]){
- return YES;
- }
- }
- return NO;
- }
-
-
- String& operator=( NSString *str)
- {
- temp = ToMutableString(str);
- return (*this);
- }
-
- String& operator=( std::string str)
- {
- temp = ToMutableString(toNSString(str));
- return (*this);
- }
-
- String& operator=( Json::Value value)
- {
- temp = ToMutableString(toNSString(value.asString()));
- return (*this);
- }
-
-
- //不區別大小寫
- BOOL isURL(){
- if ( [temp length] > 6 ) {
- NSString* prefix = [temp substringToIndex:6];
- if (stringEquals(prefix, @"http:/") || stringEquals(prefix, @"https:") ) {
- return YES;
- } else if (stringEquals(prefix, @"local:")){
- return YES;
- }
- }
- if (startWith(@"/")){
- return YES;
- }
- return NO;
- }
-
- int toInt(){
- return [temp intValue];
- }
-
- int toFloat(){
- return [temp floatValue];
- }
-
- NSDate* toDate(NSString* fmt){
- return stringToDate(temp, fmt);
- }
-
-
- NSArray* split(NSString *schar){
- return [temp componentsSeparatedByString:schar];
- }
-
- String& trim(){
- temp = ToMutableString([temp stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]);
- return (*this);
- }
-
- String& append(NSString *appstr){
- [temp appendString:appstr];
- return *this;
- }
-
-
- BOOL isEmpty(){
- return temp == nil || [temp length] == 0;
- }
-
-
- String& appendFormat(NSString* formatStr, ...){
- va_list arglist;
- va_start(arglist, formatStr);
- id statement = [[NSString alloc] initWithFormat:formatStr arguments:arglist];
- va_end(arglist);
- [temp appendString:statement];
- [statement release];
- return *this;
- }
-
- String& replace(NSString *oldStr, NSString *newStr){
- [temp replaceOccurrencesOfString:oldStr
- withString:newStr
- options:0 range:NSMakeRange(0, [temp length])];
- return *this;
- }
-
- String& regexReplace(NSString *regex, NSString *newStr){
- NSString *tempstr = temp;
- temp = ToMutableString([tempstr stringByReplacingOccurrencesOfRegex:regex withString:newStr]);
- return *this;
- }
-
- NSArray* regexMatchs(NSString *regex){
- return [temp componentsMatchedByRegex:regex];
- }
-
- NSArray* regexMatchs(NSString *regex, int capture){
- return [temp componentsMatchedByRegex:regex capture:capture];
- }
-
- BOOL regexIsMatch(NSString *regex){
- return [temp isMatchedByRegex:regex];
- }
-
-
-
- NSString * encodeUrl(){
- NSString *resultStr = temp;
-
- CFStringRef originalString = (CFStringRef) temp;
- CFStringRef leaveUnescaped = CFSTR(" ");
- CFStringRef forceEscaped = CFSTR("!*'();:@&=+$,/?%#[]");
-
- CFStringRef escapedStr;
- escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
- originalString,
- leaveUnescaped,
- forceEscaped,
- kCFStringEncodingUTF8);
-
- if(escapedStr)
- {
- NSMutableString *mutableStr = [NSMutableString stringWithString:(NSString *)escapedStr];
- CFRelease(escapedStr);
- if (!mutableStr || [mutableStr isKindOfClass:[NSNull class]] || mutableStr.length <= 0) {
- return resultStr;
- }
-
- // replace spaces with plusses
- [mutableStr replaceOccurrencesOfString:@" "
- withString:@"%20"
- options:0
- range:NSMakeRange(0, [mutableStr length])];
- resultStr = mutableStr;
- }
-
- return resultStr;
- }
-
- NSString * decodeUrl(){
- return [temp stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- }
-
- NSString * toGBK(){
- NSStringEncoding enc = CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingGB_18030_2000);
- NSData *data = [temp dataUsingEncoding:NSUTF8StringEncoding];
- return [[[NSString alloc] initWithData:data encoding:enc] autorelease];
- }
-
- NSString * toUTF8(){
- return [DZUtils urlEncode:temp stringEncode:NSUTF8StringEncoding];
- }
-
- NSData * toNSData(){
- return [temp dataUsingEncoding:NSUTF8StringEncoding];
- }
-
- NSString* subString(int start/*start from 0*/, int count){
- if(start + count <= temp.length)
- return [temp substringWithRange:NSMakeRange(start, count)];
- return nil;
- }
-
- NSString* subString(int count){
- if(count <= temp.length)
- return [temp substringToIndex: count];
- return nil;
- }
-
- static NSDate* stringToDate(NSString * string, NSString* fmt){
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- [formatter setTimeZone:[NSTimeZone defaultTimeZone]];
- NSString* format = fmt == nil ? @"yyyy-MM-dd'T'HH:mm:ss'Z'" : fmt;
- [formatter setDateFormat:format];
- NSDate *date = [formatter dateFromString:string];
- [formatter release];
- return date;
- }
-
- static NSString* dateToString(NSDate* date, NSString* fmt){
- NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
- [formatter setTimeZone:[NSTimeZone defaultTimeZone]];
- NSString* format = fmt == nil ? @"yyyy-MM-dd'T'HH:mm:ss'Z'" : fmt;
- [formatter setDateFormat:format];
- NSString* dateStr = [formatter stringFromDate:date];
- [formatter release];
- return dateStr;
- }
-
- static NSString* format(NSString* formatStr, ...){
- va_list arglist;
- va_start(arglist, formatStr);
- id statement = [[[NSString alloc] initWithFormat:formatStr arguments:arglist] autorelease];
- va_end(arglist);
- return statement;
- }
-
- static NSString* toNSString(std::string str){
- return toNSString(str.c_str());
- }
-
- static NSString* toNSString(const char* str){
- return [NSString stringWithUTF8String:str];
- }
-
- static NSString* toNSString(Json::Value value){
- return toNSString(value.asString());
- }
-
- static String Create(Json::Value value){
- String str(toNSString(value));
- return str;
- }
- };