2

I have a game that renders the player's nickname.

Normally, I use a nice, styled, bitmap font to render the nickname. However, I only have bitmaps for "normal" characters - A,B,C,...,1,2,3,...!@#$%^,.... There are no bitmaps for Chinese, Japanese or whatever other "fancy" characters in any other language.

Trying to render such text with a bitmap will crash because I don't supply such bitmaps. Therefore I decided to detect whether the given string was a "fancy" string, and if that was the case, render the nickname using some generated system font.

How can I detect if a string has fancy characters? My current solution is something like

-(BOOL)isNormalText:(NSString *)text {
    char accepted[] = {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_+{}/\\\"\'?.,"};
    for (int i = 0; i < [text length]; ++i) {
        char character = [text characterAtIndex:i];
        BOOL found = NO;
        for (int j = 0; j < 84 && !found; ++j) {
            char acceptedChar = accepted[j];
            if (character == acceptedChar) {
                found = YES;
            }
        }
        if (!found) {
            return NO;
        }
    }
    return YES;
}

Which does NOT work, I think. Because a fancy character is not one character - it is a sequence like "\u123".

I have seen a question, in Java, about something similar here: How to check if the word is Japanese or English?

They check if the character value is within the 255 range. But when I do this check in Objective-C, it tells me it is redundant because a char will always be within such range - which makes sense as I imagine the fancy characters to be actually a sequence like "\u123"...

Community
  • 1
  • 1
Saturn
  • 17,888
  • 49
  • 145
  • 271
  • 2
    Your test would work if you declared variable `character` as type `unichar`. NSString -characterAtIndex: returns UTF-16 data, and your "normal" characters will definitely look different from "fancy" characters in that encoding. Having said that, you should still use NSCharacterSet instead. – Greg Parker May 30 '14 at 01:34

2 Answers2

3

Use an NSCharacterSet, fill it with the characters that you have bitmaps for, then invert the set so that it represents all characters that you don't have. Then use -[NSString rangeOfCharacterFromSet:]. If it returns NSNotFound then the string contains only valid characters.

Just as an example to illustrate what I mean:

- (BOOL) isNormalText:(NSString *) str
{
    if (str == nil)
        return NO;

    NSCharacterSet *allowedChars = [NSCharacterSet characterSetWithCharactersInString:@"ABCDEFG"];
    NSCharacterSet *notAllowedChars = [allowedChars invertedSet];

    return [str rangeOfCharacterFromSet:notAllowedChars].location == NSNotFound;
}
dreamlax
  • 93,976
  • 29
  • 161
  • 209
1

Use regular expression checking

-(BOOL)isNormalText:(NSString *)text {
   NSString * regex        = @"(^[A-Za-z0-9]*$)";
   NSPredicate * pred      = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
   BOOL isMatch            = [pred evaluateWithObject:text];
   return isMatch;
}
Nathan Chang
  • 436
  • 2
  • 10
  • You can check your regular expression [here](http://www.regexper.com/#%22(%5E%5BA-Za-z0-9%5D*%24)%22). Feel free to add other constrain you want. (Ex: Limit string length under 20 characters) – Nathan Chang May 30 '14 at 01:18