5

如何将 NSString 中每个句子的首字母大写?例如,字符串:@"this is sentence 1. this is sentence 2! is this sentence 3? last sentence here."应该变成:@"This is sentence 1. This is sentence 2! Is this sentence 3? Last sentence here."

4

6 回答 6

3
static NSString *CapitalizeSentences(NSString *stringToProcess) {
    NSMutableString *processedString = [stringToProcess mutableCopy];


    NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en"];


    // Ironically, the tokenizer will only tokenize sentences if the first letter
    // of the sentence is capitalized...
    stringToProcess = [stringToProcess uppercaseStringWithLocale:locale];


    CFStringTokenizerRef stringTokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, (__bridge CFStringRef)(stringToProcess), CFRangeMake(0, [stringToProcess length]), kCFStringTokenizerUnitSentence, (__bridge CFLocaleRef)(locale));


    while (CFStringTokenizerAdvanceToNextToken(stringTokenizer) != kCFStringTokenizerTokenNone) {
        CFRange sentenceRange = CFStringTokenizerGetCurrentTokenRange(stringTokenizer);

        if (sentenceRange.location != kCFNotFound && sentenceRange.length > 0) {
            NSRange firstLetterRange = NSMakeRange(sentenceRange.location, 1);

            NSString *uppercaseFirstLetter = [[processedString substringWithRange:firstLetterRange] uppercaseStringWithLocale:locale];

            [processedString replaceCharactersInRange:firstLetterRange withString:uppercaseFirstLetter];
        }
    }


    CFRelease(stringTokenizer);


    return processedString;
}
于 2013-03-20T07:16:49.287 回答
1

采用

-(NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)分隔符

放置所有您期望新句子开头的分隔符(?,。,!),确保放回实际的分隔符并将数组中的第一个对象大写,然后使用

-(NSString *)componentsJoinedByString:(NSString *)分隔符

用空格分隔符将它们加入

将每个句子的第一个字母大写,对数组的所有元素运行 for 循环。

NSString *txt = @"你好!" txt = [txt stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[txt substringToIndex:1] uppercaseString]];

于 2013-03-20T04:52:01.053 回答
1

这似乎有效:

NSString *s1 = @"this is sentence 1. this is sentence 2! is this sentence 3? last sentence here.";

NSMutableString *s2 = [s1 mutableCopy];
NSString *pattern = @"(^|\\.|\\?|\\!)\\s*(\\p{Letter})";
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:NULL];
[regex enumerateMatchesInString:s1 options:0 range:NSMakeRange(0, [s1 length]) usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
    //NSLog(@"%@", result);
    NSRange r = [result rangeAtIndex:2];
    [s2 replaceCharactersInRange:r withString:[[s1 substringWithRange:r] uppercaseString]];
}];
NSLog(@"%@", s2);
// This is sentence 1. This is sentence 2! Is this sentence 3? Last sentence here.
  • "(^|\\.|\\?|\\!)"匹配字符串或“.”、“?”或“!”的开头,
  • "\\s*"匹配可选的空白,
  • "(\\p{Letter})"匹配一个字母字符。

所以这个模式找到每个句子的第一个字母。enumerateMatchesInString枚举所有匹配项并将出现的字母替换为大写字母。

于 2013-03-20T07:15:15.370 回答
1

这是我最终想出的解决方案。我创建了一个类别来使用以下方法扩展 NSString:

    -(NSString *)capitalizeFirstLetter
{
    //capitalizes first letter of a NSString
    //find position of first alphanumeric charecter (compensates for if the string starts with space or other special character)
    if (self.length<1) {
        return @"";
    }
    NSRange firstLetterRange = [self rangeOfCharacterFromSet:[NSCharacterSet alphanumericCharacterSet]];
    if (firstLetterRange.location > self.length)
        return self;

    return [self stringByReplacingCharactersInRange:NSMakeRange(firstLetterRange.location,1) withString:[[self substringWithRange:NSMakeRange(firstLetterRange.location, 1)] capitalizedString]];

}

-(NSString *)capitalizeSentences
{
    NSString *inputString = [self copy];

    //capitalize the first letter of the string
    NSString *outputStr = [inputString capitalizeFirstLetter];

    //capitalize every first letter after "."
    NSArray *sentences = [outputStr componentsSeparatedByString:@"."];
    outputStr = @"";
    for (NSString *sentence in sentences){
        static int i = 0;
        if (i<sentences.count-1)
            outputStr = [outputStr stringByAppendingString:[NSString stringWithFormat:@"%@.",[sentence capitalizeFirstLetter]]];
        else
            outputStr = [outputStr stringByAppendingString:[sentence capitalizeFirstLetter]];
        i++;
    }

    //capitalize every first letter after "?"
    sentences = [outputStr componentsSeparatedByString:@"?"];
    outputStr = @"";
    for (NSString *sentence in sentences){
        static int i = 0;
        if (i<sentences.count-1)
            outputStr = [outputStr stringByAppendingString:[NSString stringWithFormat:@"%@?",[sentence capitalizeFirstLetter]]];
        else
            outputStr = [outputStr stringByAppendingString:[sentence capitalizeFirstLetter]];
        i++;
    }
    //capitalize every first letter after "!"
    sentences = [outputStr componentsSeparatedByString:@"!"];
    outputStr = @"";
    for (NSString *sentence in sentences){
        static int i = 0;
        if (i<sentences.count-1)
            outputStr = [outputStr stringByAppendingString:[NSString stringWithFormat:@"%@!",[sentence capitalizeFirstLetter]]];
        else
            outputStr = [outputStr stringByAppendingString:[sentence capitalizeFirstLetter]];
        i++;
    }

    return outputStr;
}
@end
于 2013-03-25T00:49:27.890 回答
0

这个解决方案对我有用:

NSMutableString *processedString = [NSMutableString stringWithString:[stringToProcess uppercaseString]];
NSRange range = {0, [processedString length]};

[processedString enumerateSubstringsInRange:range options:NSStringEnumerationBySentences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {

    substringRange.location++;
    substringRange.length--;

    NSString *replacementString = [[processedString substringWithRange:substringRange] lowercaseString];
    [processedString replaceCharactersInRange:substringRange withString:replacementString];
}];

注意:正如 fumoboy007 所述,字符串需要在开头转换为大写,否则枚举无法正常工作。

于 2014-04-22T03:31:58.407 回答
0

我今天想这样做,并想出了一个可变字符串“str”,它可以包含许多句子:

    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"(^|\\.|\\!|\\?)\\s*[a-z]" options:0 error:NULL];
    for (NSTextCheckingResult* result in [regex matchesInString:str options:0 range:NSMakeRange(0, str.length)]) {
       NSRange rng = NSMakeRange(result.range.length+result.range.location-1, 1);
       [str replaceCharactersInRange:rng withString:[[str substringWithRange:rng] uppercaseString]];
    }

我的解决方案要求我只尝试将非重音拉丁字母大写,因此使用 [az]。

用perl我觉得有点长,所以我检查了堆栈溢出。除了一个类似的答案,我想我们不能比这更简单......

于 2014-05-13T23:55:18.313 回答