Changeset 5
- Timestamp:
- 12/10/06 7:35:46 PM (2 years ago)
- Files:
-
- trunk/CocoaICU.xcodeproj/project.pbxproj (modified) (3 diffs)
- trunk/source/CocoaICU.m (modified) (1 diff)
- trunk/source/ICUMatcher.h (modified) (1 diff)
- trunk/source/ICUMatcher.m (modified) (1 diff)
- trunk/source/ICUPattern.h (modified) (2 diffs)
- trunk/source/ICUPattern.m (modified) (8 diffs)
- trunk/source/NSStringICUAdditions.h (modified) (1 diff)
- trunk/source/NSStringICUAdditions.m (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/CocoaICU.xcodeproj/project.pbxproj
r3 r5 20 20 93E2C5320B1A59FC001193AC /* CocoaICU.m in Sources */ = {isa = PBXBuildFile; fileRef = 93E2C0CE0B18D142001193AC /* CocoaICU.m */; }; 21 21 /* End PBXBuildFile section */ 22 23 /* Begin PBXContainerItemProxy section */24 93E2C57C0B1A6A77001193AC /* PBXContainerItemProxy */ = {25 isa = PBXContainerItemProxy;26 containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;27 proxyType = 1;28 remoteGlobalIDString = 93E2BFE40B18BEC4001193AC;29 remoteInfo = "CocoaICU Unit Tests";30 };31 /* End PBXContainerItemProxy section */32 22 33 23 /* Begin PBXFileReference section */ … … 164 154 ); 165 155 dependencies = ( 166 93E2C57D0B1A6A77001193AC /* PBXTargetDependency */,167 156 ); 168 157 name = CocoaICU; … … 236 225 }; 237 226 /* End PBXSourcesBuildPhase section */ 238 239 /* Begin PBXTargetDependency section */240 93E2C57D0B1A6A77001193AC /* PBXTargetDependency */ = {241 isa = PBXTargetDependency;242 target = 93E2BFE40B18BEC4001193AC /* CocoaICU Unit Tests */;243 targetProxy = 93E2C57C0B1A6A77001193AC /* PBXContainerItemProxy */;244 };245 /* End PBXTargetDependency section */246 227 247 228 /* Begin XCBuildConfiguration section */ trunk/source/CocoaICU.m
r2 r5 14 14 NSString *searchString = @"bbdfdbbababababaklsdjfababababab"; 15 15 NSString *patternString = @"([ab]+)"; 16 NSArray *results = [searchString findPatternString:patternString];17 16 18 NSLog(@"%@", results);19 17 20 18 [pool release]; 21 19 return 0; 22 20 } 23 24 void doUnicodeCharSearch() {25 NSString *searchString = [NSString stringWithUTF8String:"âÆÂŽÂ®Â¢Ãç32£â¢Â£Â¢â¢Â£Â¢"];26 NSString *pattern = [NSString stringWithUTF8String:"[[:digit:]]+"];27 NSLog(@"components = %@", [searchString componentsSeparatedByPattern:[ICUPattern patternWithString:pattern]]);28 }29 30 void doSplitTest() {31 NSString *searchString = @"this is a test to see how splitting works or doesn't work";32 NSString *regex = @" ";33 NSLog(@"split = %@", [searchString componentsSeparatedByPattern:[ICUPattern patternWithString:regex]]);34 }35 36 void doGroupTest() {37 NSString *searchString = @"this is a test to see how grouping works or doesn't work.";38 NSString *regex = @"(this is a test to see how grouping) works or (doesn't work).";39 NSLog(@"groups = %@", [searchString findPatternString:regex]);40 }41 42 void doSpeedComparison() {43 NSString *pathToSomeFile = [@"~/Sandbox/CocoaICU/trunk/resources/cocoa.mbox" stringByExpandingTildeInPath];44 NSData *stringData = [NSData dataWithContentsOfMappedFile:pathToSomeFile];45 NSString *fileContents = [[NSString alloc] initWithData:stringData encoding:NSASCIIStringEncoding];46 // NSAssert(fileContents != nil, @"Cannot create string from file at path: %@", pathToSomeFile);47 48 NSString *searchTerm = @"cocoa";49 NSString *replacementTerm = @"replacementText";50 51 // /* do foundation find and replace */52 NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];53 NSCalendarDate *preCocoaFindAndReplaceTime = [NSCalendarDate date];54 NSMutableString *stringToSearch = [NSMutableString stringWithString:fileContents];55 [stringToSearch replaceOccurrencesOfString:searchTerm withString:replacementTerm options:0 range:NSMakeRange(0, [stringToSearch length])];56 NSString *resultingStringUsingFoundation = [[NSString stringWithString:stringToSearch] retain];57 NSLog(@"Foundation find/replace took %.3f seconds", [[NSDate date] timeIntervalSinceDate:preCocoaFindAndReplaceTime]);58 [innerPool release];59 60 innerPool = [[NSAutoreleasePool alloc] init];61 /* do icu find and replace */62 NSCalendarDate *preICUFindAndReplaceTime = [NSCalendarDate date];63 NSString *resultingStringUsingIcu = [fileContents findPattern:[ICUPattern patternWithString:searchTerm flags:0] replaceAllWith:replacementTerm];64 NSLog(@"ICU find/replace took %.3f seconds", [[NSDate date] timeIntervalSinceDate:preICUFindAndReplaceTime]);65 NSLog(@"done");66 67 if([resultingStringUsingFoundation isEqualToString:resultingStringUsingIcu]) {68 NSLog(@"replacement resulted in the same string");69 } else70 NSLog(@"replacement resulted in a different string");71 72 [innerPool release];73 }trunk/source/ICUMatcher.h
r3 r5 11 11 12 12 @interface ICUMatcher : NSObject { 13 13 ICUPattern *pattern; 14 14 } 15 15 16 -(BOOL)find; 16 +(ICUMatcher *)matcherWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver; 17 -(ICUMatcher *)initWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver; 18 19 -(BOOL)findNext; 17 20 -(BOOL)findFromIndex:(unsigned)index; 18 21 -(NSString *)group; 19 22 -(NSString *)groupAtIndex:(unsigned)groupIndex; 20 23 -(unsigned)numberOfGroups; 21 -(BOOL)isAtEnd; 22 -(BOOL)patternMatchesPrefix; 23 -(BOOL)patternMatchesRegion; 24 -(BOOL)lookingAt:(unsigned)index; 24 25 -(ICUPattern *)pattern; 25 -( BOOL)setMatchRegion:(NSRange)r;26 -(void)setPattern:(ICUPattern *)p; 26 27 -(NSString *)replaceAllWithString:(NSString *)aReplacementString; 27 28 -(NSString *)replaceFirstWithString:(NSString *)aReplacementString; trunk/source/ICUMatcher.m
r3 r5 8 8 9 9 #import "ICUMatcher.h" 10 10 #import "NSStringICUAdditions.h" 11 #import "ICUPattern.h" 12 13 size_t InitialGroupSize = 128; 14 15 struct URegularExpression; 16 /** 17 * Structure represeting a compiled regular rexpression, plus the results 18 * of a match operation. 19 * @draft ICU 3.0 20 */ 21 typedef struct URegularExpression URegularExpression; 22 23 #define U_HIDE_DRAFT_API 1 24 #define U_DISABLE_RENAMING 1 25 26 #import <unicode/uregex.h> 27 #import <unicode/ustring.h> 28 29 #define CheckStatus(status) if(U_FAILURE(status)) { [NSException raise:@"Find Exception" format:@"%s", u_errorName(status)]; } 30 31 32 @interface ICUMatcher (Private) 33 -(NSString *)performReplacementWithString:(NSString *)aReplacementString replaceAll:(BOOL)replacingAll; 34 @end 11 35 12 36 @implementation ICUMatcher 13 37 14 15 -(BOOL)find 16 { 38 +(ICUMatcher *)matcherWithPattern:(ICUPattern *)p overString:(NSString *)stringToSearchOver { 39 return [[[[ICUMatcher class] alloc] initWithPattern:p overString:stringToSearchOver] autorelease]; 40 } 41 42 -(ICUMatcher *)initWithPattern:(ICUPattern *)p overString:(NSString *)aStringToSearch; 43 { 44 if(![super init]) 45 return nil; 46 47 [self setPattern:p]; 48 [[self pattern] setStringToSearch:aStringToSearch]; 49 50 return self; 51 } 52 53 -(void)dealloc 54 { 55 [[self pattern] release]; 56 57 [super dealloc]; 58 } 59 60 -(void)setPattern:(ICUPattern *)p { 61 if([self pattern] != nil) 62 [[self pattern] release]; 63 64 pattern = [p retain]; 65 } 66 67 /* 68 Find the first matching substring of the input string that matches the pattern. 69 70 The search for a match begins at the specified index. If a match is found, uregex_start(), uregex_end(), and uregex_group() will provide more information regarding the match. 71 */ 72 -(BOOL)findNext { 73 URegularExpression *re = [[self pattern] re]; 74 UErrorCode status = 0; 75 UBool r = uregex_findNext(re, &status); 76 CheckStatus(status); 77 78 return r; 17 79 } 18 80 19 81 -(BOOL)findFromIndex:(unsigned)index 20 82 { 83 URegularExpression *re = [[self pattern] re]; 84 [self reset]; 85 86 UErrorCode status = 0; 87 UBool r = uregex_find(re, index, &status); 88 CheckStatus(status); 89 90 return r; 21 91 } 22 92 23 93 -(NSString *)group 24 94 { 95 NSString *stringToMatch = [[self pattern] stringToSearch]; 96 return [stringToMatch substringWithRange:[self rangeOfMatch]]; 25 97 } 26 98 27 99 -(NSString *)groupAtIndex:(unsigned)groupIndex 28 100 { 29 101 size_t groupSize = InitialGroupSize; 102 URegularExpression *re = [[self pattern] re]; 103 104 while(YES) { 105 UErrorCode status = 0; 106 UChar *dest = calloc(groupSize, sizeof(UChar)); 107 int32_t buffSize = uregex_group(re, groupIndex, dest, groupSize, &status); 108 109 if(U_BUFFER_OVERFLOW_ERROR == status) { 110 groupSize *= 2; 111 free(dest); 112 continue; 113 } 114 115 CheckStatus(status); 116 117 groupSize = InitialGroupSize; // reset to default 118 NSString *result = [[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 119 free(dest); 120 return result; 121 } 30 122 } 31 123 32 124 -(unsigned)numberOfGroups 33 125 { 34 } 35 36 -(BOOL)isAtEnd 37 { 38 } 39 40 -(BOOL)patternMatchesPrefix 41 { 42 } 43 44 -(BOOL)patternMatchesRegion 45 { 46 } 47 48 -(ICUPattern *)pattern 49 { 50 } 51 52 -(BOOL)setMatchRegion:(NSRange)r 53 { 54 } 55 56 -(NSString *)replaceAllWithString:(NSString *)aReplacementString 57 { 58 } 59 60 -(NSString *)replaceFirstWithString:(NSString *)aReplacementString 61 { 62 } 63 64 -(void)reset 65 { 126 URegularExpression *re = [[self pattern] re]; 127 UErrorCode status = 0; 128 int numberOfGroups = uregex_groupCount(re, &status); 129 CheckStatus(status); 130 131 return numberOfGroups; 132 } 133 134 -(BOOL)lookingAt:(unsigned)index { 135 UErrorCode status = 0; 136 URegularExpression *re = [[self pattern] re]; 137 BOOL matches = uregex_lookingAt(re, 0, &status); 138 CheckStatus(status); 139 return matches; 140 } 141 142 -(ICUPattern *)pattern { 143 return pattern; 144 } 145 146 -(NSString *)performReplacementWithString:(NSString *)aReplacementString replaceAll:(BOOL)replacingAll { 147 UErrorCode status = 0; 148 UChar *replacementText = [aReplacementString UTF16String]; 149 URegularExpression *re = [[self pattern] re]; 150 int searchTextLength = [[[self pattern] stringToSearch] length]; 151 152 BOOL replacementCompleted = NO; 153 int resultLength = 0; 154 size_t destStringBufferSize = searchTextLength * 2; 155 UChar *destString = NULL; 156 while(!replacementCompleted) { 157 158 destString = calloc(destStringBufferSize, sizeof(UChar)); 159 if(replacingAll) 160 resultLength = uregex_replaceAll(re, replacementText, -1, destString, destStringBufferSize, &status); 161 else 162 resultLength = uregex_replaceFirst(re, replacementText, -1, destString, destStringBufferSize, &status); 163 164 if(status == U_BUFFER_OVERFLOW_ERROR) { 165 status = 0; 166 free(destString); 167 destStringBufferSize *= 2; 168 } 169 else if(U_FAILURE(status)) { 170 free(destString); 171 [NSException raise:@"Find Exception" 172 format:@"Could not perform find and replace: %s", u_errorName(status)]; 173 } else { 174 replacementCompleted = YES; 175 } 176 } 177 178 NSString *result = [[[NSString alloc] initWithBytes:destString 179 length:resultLength * sizeof(UChar) 180 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 181 free(destString); 182 return result; 183 } 184 185 186 -(NSString *)replaceAllWithString:(NSString *)aReplacementString { 187 return [self performReplacementWithString:aReplacementString replaceAll:YES]; 188 } 189 190 -(NSString *)replaceFirstWithString:(NSString *)aReplacementString { 191 return [self performReplacementWithString:aReplacementString replaceAll:NO]; 192 } 193 194 -(void)reset { 195 [[self pattern] reset]; 66 196 } 67 197 68 198 -(NSRange)rangeOfMatch 69 199 { 200 return [self rangeOfMatchGroup:0]; 70 201 } 71 202 72 203 -(NSRange)rangeOfMatchGroup:(unsigned)groupNumber 73 204 { 74 } 75 76 205 UErrorCode status = 0; 206 URegularExpression *re = [[self pattern] re]; 207 int start = uregex_start(re, groupNumber, &status); 208 CheckStatus(status); 209 210 int end = uregex_end(re, groupNumber, &status); 211 CheckStatus(status); 212 return NSMakeRange(start, end-start); 213 } 77 214 78 215 @end trunk/source/ICUPattern.h
r2 r5 21 21 22 22 @interface ICUPattern: NSObject <NSCopying> { 23 void * pattern;23 void *re; 24 24 void *textToSearch; 25 25 unsigned flags; … … 32 32 -(id)initWithString:(NSString *)aPattern flags:(unsigned)flags; 33 33 34 +(ICUMatcher *)matcherForString:(NSString *)stringToSearchOver; 35 36 -(void *)pattern; 37 38 /* no retain done. the life of the text is given by the caller */ 39 -(void)setTextToSearch:(NSString *)s; 40 -(void *)textToSearch; 41 42 34 -(NSArray *)componentsSplitFromString:(NSString *)stringToSplit; 35 -(BOOL)matchesString:(NSString *)stringToMatchAgainst; 36 -(NSString *)pattern; 37 -(void)setStringToSearch:(NSString *)aStringToSearchOver; 38 -(NSString *)stringToSearch; 43 39 -(void)reset; 44 40 41 -(void *)re; 45 42 @end trunk/source/ICUPattern.m
r2 r5 7 7 // 8 8 // more info: http://icu.sourceforge.net/apiref/icu4c/uregex_8h.html 9 // 10 // inspiration: http://java.sun.com/j2se/1.5.0/docs/api/index.html?java/util/regex/Pattern.html 11 // 9 12 10 13 #import "ICUPattern.h" … … 32 35 33 36 @interface ICUPattern (Private) 34 -(void)set Pattern:(void*)p;37 -(void)setRe:(URegularExpression *)p; 35 38 -(unsigned)flags; 36 39 -(UChar *)textToSearch; 40 //-(URegularExpression *)re; 41 -(void)setTextToSearch:(UChar *)utf16String; 42 37 43 @end 38 44 … … 54 60 textToSearch = NULL; 55 61 flags = f; 56 62 57 63 UParseError err; 58 64 UErrorCode status = 0; … … 65 71 } 66 72 67 [self set Pattern:e];73 [self setRe:e]; 68 74 69 75 return self; … … 76 82 -(void)dealloc { 77 83 78 if( pattern!= NULL)79 free( pattern);84 if(re != NULL) 85 free(re); 80 86 81 87 [super dealloc]; 82 88 } 83 89 90 -(NSString *)stringToSearch 91 { 92 return [NSString stringWithUTF16String:[self textToSearch]]; 93 } 94 95 -(void)setStringToSearch:(NSString *)aStringToSearchOver 96 { 97 [self setTextToSearch:[aStringToSearchOver UTF16String]]; 98 } 99 100 -(void)setTextToSearch:(UChar *)utf16String { 101 UErrorCode status = 0; 102 103 uregex_setText([self re], utf16String, -1, &status); 104 105 textToSearch = utf16String; 106 107 if(U_FAILURE(status)) { 108 textToSearch = NULL; 109 [NSException raise:@"Invalid String Exception" 110 format:@"Could not set text to match against: %s", u_errorName(status)]; 111 } 112 } 113 114 -(UChar *)textToSearch { 115 return (UChar *)textToSearch; 116 } 117 84 118 - (id)copyWithZone:(NSZone *)zone { 85 119 … … 87 121 88 122 UErrorCode status = 0; 89 URegularExpression *r = uregex_clone([self pattern], &status);123 URegularExpression *r = uregex_clone([self re], &status); 90 124 if(U_FAILURE(status)) 91 125 [NSException raise:@"Copy Exception" 92 126 format:@"Could not copy pattern: %s", u_errorName(status)]; 93 127 94 [p setTextToSearch:[self textToSearch]]; // no copy! 95 [p setPattern:r]; 128 [p setRe:r]; 96 129 97 130 return p; 98 131 } 99 132 100 101 133 -(void)reset { 102 134 UErrorCode status = 0; 103 uregex_reset([self pattern], 0, &status);135 uregex_reset([self re], 0, &status); 104 136 105 137 if(U_FAILURE(status)) { … … 113 145 } 114 146 115 -(void)setTextToSearch:(NSString *)s { 116 UErrorCode status = 0; 117 URegularExpression *re = [self pattern]; 118 119 UChar *aString = [s UTF16String]; 120 121 uregex_setText(re, aString, -1, &status); 122 123 textToSearch = aString; 124 125 if(U_FAILURE(status)) { 126 [NSException raise:@"Invalid String Exception" 127 format:@"Could not set text to match against: %s", u_errorName(status)]; 128 } 129 } 130 131 -(void *)textToSearch { 132 return textToSearch; 133 } 134 135 -(void *)pattern { 136 return pattern; 137 } 138 139 -(void)setPattern:(void *)p { 140 if(pattern != NULL) 141 free(pattern); 142 143 pattern = p; 147 -(NSString *)pattern { 148 return [self description]; 149 } 150 151 -(void)setRe:(URegularExpression *)p { 152 if(re != NULL) 153 free(re); 154 155 re = p; 156 } 157 158 -(void *)re 159 { 160 return re; 144 161 } 145 162 146 163 -(NSString *)description { 147 164 148 if([self pattern] != NULL) {165 if([self re] != NULL) { 149 166 UChar *p = NULL; 150 167 UErrorCode status = 0; 151 168 int len = 0; 152 p = (UChar *)uregex_pattern([self pattern], &len, &status);169 p = (UChar *)uregex_pattern([self re], &len, &status); 153 170 154 171 if(U_FAILURE(status)) { … … 163 180 } 164 181 182 -(NSArray *)componentsSplitFromString:(NSString *)stringToSplit 183 { 184 [self setTextToSearch:[stringToSplit UTF16String]]; 185 BOOL isDone = NO; 186 UErrorCode status = 0; 187 188 NSMutableArray *results = [NSMutableArray array]; 189 int destFieldsCapacity = 2; 190 size_t destCapacity = u_strlen([self textToSearch]); 191 192 while(!isDone) { 193 UChar *destBuf = calloc(destCapacity, sizeof(UChar)); 194 int requiredCapacity = 0; 195 UChar *destFields[destFieldsCapacity]; 196 int numberOfComponents = uregex_split([self re], 197 destBuf, 198 destCapacity, 199 &requiredCapacity, 200 destFields, 201 destFieldsCapacity, 202 &status); 203 204 if(status == U_BUFFER_OVERFLOW_ERROR) { // buffer was too small, grow it 205 free(destBuf); 206 NSAssert(destCapacity * 2 < INT_MAX, @"Overflow occurred splitting string."); 207 destCapacity = (destCapacity < requiredCapacity) ? requiredCapacity : destCapacity * 2; 208 status = 0; 209 } else if(destFieldsCapacity == numberOfComponents) { 210 destFieldsCapacity *= 2; 211 NSAssert(destFieldsCapacity *2 < INT_MAX, @"Overflow occurred splitting string."); 212 free(destBuf); 213 status = 0; 214 } else if(U_FAILURE(status)) { 215 free(destBuf); 216 isDone = YES; 217 } else { 218 int i; 219 220 for(i=0; i<numberOfComponents; i++) { 221 NSAssert(i < destFieldsCapacity, @"Unexpected number of components found in split."); 222 UChar *offsetStart = destFields[i]; 223 [results addObject:[NSString stringWithUTF16String:offsetStart]]; 224 } 225 isDone = YES; 226 } 227 } 228 229 if(U_FAILURE(status)) 230 [NSException raise:@"Split Exception" 231 format:@"Unable to split string: %@", u_errorName(status)]; 232 233 return [NSArray arrayWithArray:results]; 234 } 235 236 -(BOOL)matchesString:(NSString *)stringToMatchAgainst 237 { 238 [self setTextToSearch:[stringToMatchAgainst UTF16String]]; 239 240 UErrorCode status = 0; 241 BOOL matches = uregex_matches([self re], 0, &status); 242 if(U_FAILURE(status)) { 243 [NSException raise:@"Match Exception" 244 format:@"Could not perform match: %s", u_errorName(status)]; 245 } 246 247 return matches; 248 } 249 165 250 @end trunk/source/NSStringICUAdditions.h
r2 r5 12 12 @interface NSString (NSStringICUAdditions) 13 13 14 -(NSArray *)findPatternString:(NSString *)p; 15 -(NSArray *)findPattern:(ICUPattern *)p; 16 17 -(NSString *)findPattern:(ICUPattern *)p replaceAllWith:(NSString *)replacementString; 18 19 -(BOOL)matchesPattern:(ICUPattern *)p; 20 -(BOOL)matchesPatternString:(NSString *)anExpression; 21 22 -(BOOL)findNext; 23 -(NSRange *)rangeOfCurrentMatch; 24 25 -(NSArray *)componentsSeparatedByPattern:(ICUPattern *)p; 26 -(NSArray *)componentsSeparatedByPatternString:(NSString *)s; 27 14 +(NSString *)stringWithUTF16String:(void *)utf16EncodedString; 28 15 -(void *)UTF16String; 29 16 trunk/source/NSStringICUAdditions.m
r3 r5 22 22 #import <unicode/uregex.h> 23 23 24 size_t InitialGroupSize = 128; 24 25 25 26 26 @interface NSString (NSStringICUPrivateAdditions) 27 27 @end 28 28 29 @implementation NSString (NSStringICUAdditions) 29 @implementation NSString (NSStringICUAdditions)// 30 // 31 //-(NSArray *)findPattern:(ICUPattern *)p { 32 // [p setStringToSearch:self]; 33 // 34 // UErrorCode status = 0; 35 // int32_t numberOfGroups = uregex_groupCount((URegularExpression *)[p pattern], &status); 36 // 37 // if(U_FAILURE(status)) { 38 // [NSException raise:@"Find Exception" 39 // format:@"%s", u_errorName(status)]; 40 // } 41 // 42 // BOOL match = uregex_matches([p pattern], 0, &status); 43 // if(U_FAILURE(status)) { 44 // [NSException raise:@"Find Exception" 45 // format:@"%s", u_errorName(status)]; 46 // } 47 // 48 // if(!match) 49 // return [NSArray array]; 50 // 51 // NSMutableArray *results = [NSMutableArray array]; 52 // int i; 53 // 54 // size_t groupSize = InitialGroupSize; 55 // for(i=0; i<numberOfGroups+1; i++) { 56 // status = 0; 57 // UChar *dest = calloc(groupSize, sizeof(UChar)); 58 // int32_t buffSize = uregex_group([p pattern], i, dest, groupSize, &status); 59 // 60 // if(U_BUFFER_OVERFLOW_ERROR == status) { 61 // groupSize *= 2; 62 // free(dest); 63 // i--; 64 // continue; 65 // } 66 // else if(U_FAILURE(status)) { 67 // [NSException raise:@"Find Exception" 68 // format:@"%s", u_errorName(status)]; 69 // } 70 // 71 // groupSize = InitialGroupSize; // reset to default 72 // [results addObject:[[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]]; 73 // free(dest); 74 // } 75 // 76 // return [NSArray arrayWithArray:results]; 77 //} 30 78 31 -(NSString *)findPatternString:(NSString *)p replaceAllWith:(NSString *)replacementString {32 ICUPattern *pattern = [ICUPattern patternWithString:p];33 return [self findPattern:pattern replaceAllWith:replacementString];34 }35 79 36 -(NSArray *)findPatternString:(NSString *)p { 37 ICUPattern *pattern = [ICUPattern patternWithString:p]; 38 return [self findPattern:pattern]; 39 } 40 41 -(NSArray *)findPattern:(ICUPattern *)p { 42 [p setTextToSearch:self]; 43 44 UErrorCode status = 0; 45 int32_t numberOfGroups = uregex_groupCount((URegularExpression *)[p pattern], &status); 46 47 if(U_FAILURE(status)) { 48 [NSException raise:@"Find Exception" 49 format:@"%s", u_errorName(status)]; 50 } 51 52 BOOL match = uregex_matches([p pattern], 0, &status); 53 if(U_FAILURE(status)) { 54 [NSException raise:@"Find Exception" 55 format:@"%s", u_errorName(status)]; 56 } 57 58 if(!match) 59 return [NSArray array]; 60 61 NSMutableArray *results = [NSMutableArray array]; 62 int i; 63 64 size_t groupSize = InitialGroupSize; 65 for(i=0; i<numberOfGroups+1; i++) { 66 status = 0; 67 UChar *dest = calloc(groupSize, sizeof(UChar)); 68 int32_t buffSize = uregex_group([p pattern], i, dest, groupSize, &status); 69 70 if(U_BUFFER_OVERFLOW_ERROR == status) { 71 groupSize *= 2; 72 free(dest); 73 i--; 74 continue; 75 } 76 else if(U_FAILURE(status)) { 77 [NSException raise:@"Find Exception" 78 format:@"%s", u_errorName(status)]; 79 } 80 81 groupSize = InitialGroupSize; // reset to default 82 [results addObject:[[[NSString alloc] initWithBytes:dest length:buffSize*sizeof(UChar) encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]]; 83 free(dest); 84 } 85 86 return [NSArray arrayWithArray:results]; 87 } 88 89 -(NSString *)findPattern:(ICUPattern *)p replaceAllWith:(NSString *)replacementString { 90 [p setTextToSearch:self]; 91 92 UErrorCode status = 0; 93 UChar *replacementText = [replacementString UTF16String]; 94 95 BOOL replacementCompleted = NO; 96 int32_t resultLength = 0; 97 size_t destStringBufferSize = [self length] * 2; 98 UChar *destString = NULL; 99 while(!replacementCompleted) { 100 101 destString = calloc(destStringBufferSize, sizeof(UChar)); 102 resultLength = uregex_replaceAll([p pattern], replacementText, -1, destString, destStringBufferSize, &status); 103 104 if(status == U_BUFFER_OVERFLOW_ERROR) { 105 status = 0; 106 free(destString); 107 destStringBufferSize *= 2; 108 } 109 else if(U_FAILURE(status)) { 110 free(destString); 111 [NSException raise:@"Find and Replace All Exception" 112 format:@"Could not perform find and replace: %s", u_errorName(status)]; 113 } else { 114 replacementCompleted = YES; 115 } 116 } 117 118 NSString *result = [[[NSString alloc] initWithBytes:destString 119 length:resultLength * sizeof(UChar) 120 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 121 free(destString); 122 return result; 123 } 124 125 -(BOOL)findNext 80 +(NSString *)stringWithUTF16String:(void *)utf16EncodedString 126 81 { 127 UErrorCode status = 0; 128 // BOOL r = uregex_findNext([ 129 } 130 131 -(NSRange *)rangeOfCurrentMatch 132 { 133 134 } 135 136 -(NSArray *)componentsSeparatedByPatternString:(NSString *)s 137 { 138 return [self componentsSeparatedByPattern:[ICUPattern patternWithString:s]]; 139 } 140 141 -(NSArray *)componentsSeparatedByPattern:(ICUPattern *)p { 142 [p setTextToSearch:self]; 143 BOOL isDone = NO; 144 UErrorCode status = 0; 145 146 NSMutableArray *results = [NSMutableArray array]; 147 int destFieldsCapacity = 2; 148 size_t destCapacity = u_strlen([p textToSearch]); 149 150 while(!isDone) { 151 UChar *destBuf = calloc(destCapacity, sizeof(UChar)); 152 int requiredCapacity = 0; 153 UChar *destFields[destFieldsCapacity]; 154 int numberOfComponents = uregex_split([p pattern], 155 destBuf, 156 destCapacity, 157 &requiredCapacity, 158 destFields, 159 destFieldsCapacity, 160 &status); 161 162 if(status == U_BUFFER_OVERFLOW_ERROR) { // buffer was too small, grow it 163 free(destBuf); 164 NSAssert(destCapacity * 2 < INT_MAX, @"Overflow occurred splitting string."); 165 destCapacity = (destCapacity < requiredCapacity) ? requiredCapacity : destCapacity * 2; 166 status = 0; 167 } else if(destFieldsCapacity == numberOfComponents) { 168 destFieldsCapacity *= 2; 169 NSAssert(destFieldsCapacity *2 < INT_MAX, @"Overflow occurred splitting string."); 170 free(destBuf); 171 status = 0; 172 } else if(U_FAILURE(status)) { 173 free(destBuf); 174 isDone = YES; 175 } else { 176 int i; 177 178 for(i=0; i<numberOfComponents; i++) { 179 NSAssert(i < destFieldsCapacity, @"Unexpected number of components found in split."); 180 UChar *offsetStart = destFields[i]; 181 182 NSString *component = [[[NSString alloc] initWithBytes:offsetStart 183 length:u_strlen(offsetStart)*sizeof(UChar) 184 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 185 [results addObject:component]; 186 } 187 isDone = YES; 188 } 189 } 190 191 if(U_FAILURE(status)) 192 [NSException raise:@"Split Exception" 193 format:@"Unable to split string: %@", u_errorName(status)]; 194 195 return [NSArray arrayWithArray:results]; 82 return [[[NSString alloc] initWithBytes:utf16EncodedString 83 length:u_strlen(utf16EncodedString)*sizeof(UChar) 84 encoding:CFStringConvertEncodingToNSStringEncoding(kCFStringEncodingUTF16)] autorelease]; 196 85 } 197 86 … … 205 94 } 206 95 207 -(BOOL)matchesPattern:(ICUPattern *)p {208 [p setTextToSearch:self];209 210 UErrorCode status = 0;211 BOOL matches = uregex_matches([p pattern], 0, &status);212 if(U_FAILURE(status)) {213 [NSException raise:@"Match Exception"214 format:@"Could not perform match: %s", u_errorName(status)];215 }216 217 return matches;218 }219 220 -(BOOL)matchesPatternString:(NSString *)anExpression {221 return [self matchesPattern:[ICUPattern patternWithString:anExpression]];222 }223 224 96 @end