【问题标题】:Get the unique characters in an NSString获取 NSString 中的唯一字符
【发布时间】:2013-11-13 10:11:11
【问题描述】:

如何获取NSString 中的唯一字符?

我要做的是获取NSString 中的所有非法字符,以便我可以提示用户输入了哪些字符,因此需要将其删除。我首先定义一个合法字符的NSCharacterSet,将它们与每个合法字符的出现分开,并将剩下的(只有非法字符)加入一个新的NSString。我现在正计划获取新 NSString 的独特字符(希望是一个数组),但我在任何地方都找不到参考。

NSCharacterSet *legalCharacterSet = [NSCharacterSet
    characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-()&+:;,'.# "];

NSString *illegalCharactersInTitle = [[self.titleTextField.text.noWhitespace
    componentsSeparatedByCharactersInSet:legalCharacterSet]
    componentsJoinedByString:@""];

【问题讨论】:

  • 为什么不对文本字段应用格式化程序,这样就不可能输入非法字符。这将提供一个更实用的解决方案。
  • 大佬要我显示显示了哪些非法字符。我认为这真的很愚蠢,但我只是一个程序员。
  • 不将它们分开而是使用NSAttributedString 在原始文本中突出显示它们怎么样?只需从一个新的属性可变字符串开始,循环遍历所有字符并附加它们,如果它们是非法的,则将它们附加为红色。

标签: ios iphone objective-c cocoa-touch nsstring


【解决方案1】:

这应该对你有帮助。我找不到任何可以使用的函数。

NSMutableSet *uniqueCharacters = [NSMutableSet set];
NSMutableString *uniqueString = [NSMutableString string];
[illegalCharactersInTitle enumerateSubstringsInRange:NSMakeRange(0, illegalCharactersInTitle.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
    if (![uniqueCharacters containsObject:substring]) {
        [uniqueCharacters addObject:substring];
        [uniqueString appendString:substring];
    }
}];

【讨论】:

  • +1 for -enumerateSubstringsInRange:...NSStringEnumerationByComposedCharacterSequences 但请参阅我的答案以了解有关计算 illegalCharactersInTitle 的方式的额外警告。
【解决方案2】:

尝试对您的代码进行以下修改:

// legal set
NSCharacterSet *legalCharacterSet = [NSCharacterSet
                                         characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789-()&+:;,'.# "];

// test strings
NSString *myString = @"LegalStrin()";
//NSString *myString = @"francesco@gmail.com"; illegal string


NSMutableCharacterSet *stringSet = [NSCharacterSet characterSetWithCharactersInString:myString];
// inverts the set
NSCharacterSet *illegalCharacterSet = [legalCharacterSet invertedSet];

// intersection of the string set and the illegal set that modifies the mutable stringset itself
[stringSet formIntersectionWithCharacterSet:illegalCharacterSet];

// prints out the illegal characters with the convenience method
NSLog(@"IllegalStringSet: %@", [self stringForCharacterSet:stringSet]);

我调整了从another stackoverflow question打印的方法:

- (NSString*)stringForCharacterSet:(NSCharacterSet*)characterSet
{
    NSMutableString *toReturn = [@"" mutableCopy];
    unichar unicharBuffer[20];
    int index = 0;

    for (unichar uc = 0; uc < (0xFFFF); uc ++)
    {
        if ([characterSet characterIsMember:uc])
        {
            unicharBuffer[index] = uc;

            index ++;

            if (index == 20)
            {
                NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
                [toReturn appendString:characters];

                index = 0;
            }
        }
    }

    if (index != 0)
    {
        NSString * characters = [NSString stringWithCharacters:unicharBuffer length:index];
        [toReturn appendString:characters];
    }
    return toReturn;
}

【讨论】:

    【解决方案3】:

    首先,你必须小心你认为的字符。 NSString 的 API 在谈论 Unicode 所指的 UTF-16 代码单元时使用了字符一词,但是孤立地处理代码单元不会给您用户所认为的字符。例如,有组合字符与前一个字符组成以产生不同的字形。此外,还有代理对,只有在配对时才有意义。

    因此,您实际上需要收集包含用户认为的字符的子字符串。

    我正要编写与 Grzegorz Krukowski 的答案非常相似的代码。他打败了我,所以我不会,但我会补充说,由于我上面引用的原因,你过滤掉合法字符的代码被破坏了。例如,如果文本包含“é”并且它被分解为“e”加上一个组合重音符号,那么您的代码将去掉“e”,留下一个悬空的组合重音符号。我相信您的意图是将“é”视为非法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      相关资源
      最近更新 更多