如何计算NSString对象中的非字母数字字符数?

时间:2010-11-16 04:14:25

标签: iphone ipad ios nsstring

我正在深入研究iOS开发,我仍然熟悉NSString对象。我正处于需要计算字符串中非字母数字字符数的位置。我提出的一种方法是从字符串中剥离非字母数字字符,然后从原始字符串的长度中减去剥离字符串的长度,就像这样......

NSCharacterSet *nonalphanumericchars = [[NSCharacterSet alphanumericCharacterSet ] invertedSet];

NSString *trimmedString = [originalString stringByTrimmingCharactersInSet:nonalphanumericchars];

NSInteger numberOfNonAlphanumericChars = [originalString length] - [trimmedString length];

但它不起作用。计数始终为零。如何计算NSString对象中非字母数字字符的数量?

非常感谢你的智慧!

3 个答案:

答案 0 :(得分:6)

你的方法的问题是你没有剥离角色,你正在修剪它们。这意味着只从符合集合的字符串末尾剥离字符(中间没有任何东西)。

为此,您可以迭代字符串并测试每个字符不是字母数字集的成员。例如:

NSString* theString = // assume this exists
NSMutableCharacterSet* testCharSet = [[NSMutableCharacterSet alloc] init];
[testCharSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
[testCharSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
NSUInteger length = [theString length];
NSUInteger totalNonAlnumCharacters = length;
for( NSUInteger i = 0; i < length; i++ ) {
  if( [testCharSet characterIsMember:[theString characterAtIndex:i]] )
    totalNonAlnumCharacters--;
}
NSLog(@"Number of non-alphanumeric characters in string: %lu", (long int)totalNonAlnumCharacters);
[testCharSet release];

答案 1 :(得分:2)

由于您提到过使用stringByTrimmingCharactersInSet:尝试过它,因此了解实际上只有框架调用才能实现此方法可能会很有趣。借用Jason的设置代码

NSString* theString = // assume this exists
NSMutableCharacterSet* testCharSet = [[NSMutableCharacterSet alloc] init];
[testCharSet formUnionWithCharacterSet:[NSCharacterSet alphanumericCharacterSet]];
[testCharSet formUnionWithCharacterSet:[NSCharacterSet whitespaceCharacterSet]];
然后,您可以通过以下方式抛弃for循环:

NSArray *nonComp = [theString componentsSeparatedByCharactersInSet:testCharSet];

它会在每个索引处将字符串分开,它会从字符集中找到一个字符,从而创建剩余部分的数组。然后,您可以使用键值编码来汇总所有部分的长度属性:

NSNumber *numberOfNonANChars = [nonComp valueForKeyPath:@"@sum.length"];

或者说,再次将碎片粘在一起并计算长度:

NSUInteger nonANChars = [[nonComp componentsJoinedByString:@""] length];

但是:拆分组件将创建一个数组和计数后不需要的字符串 - 无意义的内存分配(对于componentsJoinedByString :)也是如此。并且使用valueForKeyPath:对于这个非常简单的求和,似乎比仅仅迭代原始字符串要昂贵得多。

代码可能更加面向对象,甚至更不容易出错,但在这两种情况下,性能都会比Jason的代码差几个数量级。因此,在这种情况下,良好的旧for循环将最大程度地滥用框架功能(因为所使用的方法不适用于此)。

答案 2 :(得分:-2)

NSString *str=@"str56we90";
int count;

for(int i=0;i<[str length];i++)
{
    int str1=(int)[str characterAtIndex:i];
    NSString *temp=[NSString stringWithFormat:@"%C",str1];

    if(str1 >96 && str1 <123  || str1 >64 && str1 <91)

        count=count +1;
}

int finalResult = [str length] - count;

计数将是您的最终结果。