Re: NSString "replace" method ?
Re: NSString "replace" method ?
- Subject: Re: NSString "replace" method ?
- From: Stefan Jung <email@hidden>
- Date: Wed, 16 Jan 2002 19:14:22 +0100
Following is a comment from Ali I found in my personal archive,
Stefan
Unless you are doing a strict 1-to-1 replacement of chars, I think any
attempts to mutate a string in place might be bad as it might end up
copying data around too much, so your approach (read the source string,
create a new modified string) is probably the best.
TextEdit's TextFinder.m class does its find and replace in a pretty fast
way; replacing 6000 instances in a 200K text doc is less than a second,
for instance. But that works on attributed strings, and also updates
the display. In addition, it generates a lot of autoreleased strings,
but is careful to try to keep a lid on the memory usage. Below is a
simpler version which works on NSStrings; according to my measurements
it can replace 10000 instances in a 150 page doc in 0.15 sec. A 1000
page doc (60,000 lines) takes 1 sec. I think a faster version can be
achieved by avoiding the autoreleasing --- copy the chars from source
to destination yourself, either using getCharacters: with a stack sized
buffer (say 1000 chars), or using the CFInlineBuffer functions from
CFString.h to read chars one at a time (but efficiently).
Ali
#import <Foundation/Foundation.h>
NSString *replace(NSString *textContents, NSString *targetString,
NSString *replaceString) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableString *temp = [[NSMutableString alloc] init];
NSRange replaceRange = NSMakeRange(0, [textContents length]);
NSRange rangeInOriginalString = replaceRange; /* Range in the
original string where we do the searches */
int replaced = 0;
// The following loop can execute an unlimited number of times, and
it could have autorelease activity.
// To keep things under control, we use a pool, but to be a bit
efficient, instead of emptying everytime through
// the loop, we do it every so often. We can only do this as long as
autoreleased items are not supposed to
// survive between the invocations of the pool!
while (1) {
NSRange rangeToCopy;
NSRange foundRange = [textContents rangeOfString:targetString
options:0 range:rangeInOriginalString];
// Because we computed the tightest range above, foundRange
should always be valid.
if (foundRange.length == 0) break;
rangeToCopy = NSMakeRange(rangeInOriginalString.location,
foundRange.location - rangeInOriginalString.location);
[temp appendString:[textContents
substringWithRange:rangeToCopy]];
[temp appendString:replaceString];
rangeInOriginalString.length -= NSMaxRange(foundRange) -
rangeInOriginalString.location;
rangeInOriginalString.location = NSMaxRange(foundRange);
replaced++;
if (replaced % 100 == 0) { // Refresh the pool... See warning
above!
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
}
if (rangeInOriginalString.length > 0) [temp
appendString:[textContents substringWithRange:rangeInOriginalString]];
[pool release];
return [temp autorelease];
}
Am Mittwoch den, 16. Januar 2002, um 12:25, schrieb Jens Bauer:
Hi,
Does anyone know if there is a way to replace a string inside another
string with a third string ?
. such as
[hugeStr replace:@"%{address}" with:@"Infinite Loop 1"];
?
Love,
Jens
--
If you ever wondered how it would be, when everything just works for
you,
the new iMac is for you. See http://www.apple.com/
--
Jens Bauer, Faster Software.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.