Xetius
Xetius

Reputation: 46794

Transforming string in Objective-C for iPhone

Given the following sequence:

"normal %(b)BOLD% normal"

I want to transform this into the following string:

"0000000%(b)bbbb%0000000"

In other words, '%(b)' specifies that all characters up until the next '%' should be 'b'. All other characters should be '0'.

I have tried numerous approaches, including using the RegexKitLite regular expression library but cannot seem to get my head around it.

Can anyone give me some pointers?

Upvotes: 0

Views: 545

Answers (3)

NSResponder
NSResponder

Reputation: 16861

Doesn't look to me like NSScanner is called for here. See -rangeOfString: and -rangeOfString:options: in the NSString documentation.

Upvotes: 0

Dave DeLong
Dave DeLong

Reputation: 243156

Yeah, using regexes was my gut reaction too, but with your requirements, it'd probably be simpler just to scan the string. Since you're dealing with individual characters, this will also be easiest to do in C. So here are a couple pointers:

const char * original = [@"normal %(b)BOLD% normal" UTF8String];
char * mutable = malloc((strlen(original)+1) * sizeof(char));
//we have to make a copy of the characters because we can't modify an NSString directly
strcpy(mutable, original);

//just a couple flags
char * pointer = mutable;
int isInBoldBlock = 0;
//loop until the end of the string
while (*pointer != '\0') {
  if (isInBoldBlock) {
    if (*pointer != '%') {
      //we're in a bold block and found a char that isn't %
      *pointer = 'b';
    } else {
      //we found the end of the bold block
      isInBoldBlock = 0;
    }
  } else {
    //look to see if we're going to start a bold section
    if (*pointer == '%' && *(pointer+1) == '(' && *(pointer+2) == 'b' && *(pointer+3) == ')') {
      isInBoldBlock = 1;
      pointer += 3; //skip the %(b) characters
    } else {
      //we're not in a bold block, and we're not about to start one:
      *pointer = '0';
    }
  }
  //move to the next character
  pointer++;
}

//this will create a copy of "mutable"
NSString * final = [[NSString alloc] initWithUTF8String:mutable];
//free the memory we allocated
free(mutable);
NSLog(@"Final: %@", final);
//release the constructed string
[final release];

There might be a more "Cocoa" way to do this, particularly with NSScanner, but I am unfamiliar with this class, and the above method works.

CAVEAT IMPLEMENTOR: the "%(b)" and closing "%" bits MUST be the ASCII characters. This will behave strangely if you have beyond-ascii characters in the string. Consider transforming the string to ASCII before using this (with -[NSString dataUsingEncoding:allowLossyConversion:]).

Upvotes: 1

BitDrink
BitDrink

Reputation: 1193

You can use the NSScanner to scan the source string and locate the place holders ('%(b)' and '%') ... then use the locations (I mean to the filed 'location' of a NSRange struct) to modify the source string as you want!

P.S: I'm sorry for my english! :-(

Upvotes: 1

Related Questions