如何将 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."
6 回答
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;
}
采用
-(NSArray *)componentsSeparatedByCharactersInSet:(NSCharacterSet *)分隔符
放置所有您期望新句子开头的分隔符(?,。,!),确保放回实际的分隔符并将数组中的第一个对象大写,然后使用
-(NSString *)componentsJoinedByString:(NSString *)分隔符
用空格分隔符将它们加入
将每个句子的第一个字母大写,对数组的所有元素运行 for 循环。
NSString *txt = @"你好!" txt = [txt stringByReplacingCharactersInRange:NSMakeRange(0,1) withString:[[txt substringToIndex:1] uppercaseString]];
这似乎有效:
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
枚举所有匹配项并将出现的字母替换为大写字母。
这是我最终想出的解决方案。我创建了一个类别来使用以下方法扩展 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
这个解决方案对我有用:
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 所述,字符串需要在开头转换为大写,否则枚举无法正常工作。
我今天想这样做,并想出了一个可变字符串“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我觉得有点长,所以我检查了堆栈溢出。除了一个类似的答案,我想我们不能比这更简单......