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 *)separator
新しい文の始まりを期待するすべてのセパレーター(?、。、!)を配置し、実際のセパレーターを元に戻し、配列の最初のオブジェクトを大文字にしてから、
-(NSString *)componentsJoinedByString:(NSString *)separator
スペース区切り文字でそれらを結合します
各文の最初の文字を大文字にするために、配列のすべての要素に対してforループを実行します。
NSString * txt = @ "hello!" txt = [txt stringByReplacingCharactersInRange:NSMakeRange(0,1)withString:[[txt substringToIndex:1] uppercaseString]];
これが私が最終的に思いついた解決策です。次のメソッドで 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
This seems to work:
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.
"(^|\\.|\\?|\\!)"
matches the start of the string or ".", "?", or "!","\\s*"
matches optional white space,"(\\p{Letter})"
matches a letter character.
So this pattern finds the first letter of each sentence. enumerateMatchesInString
enumerates all the matches and replaces the occurrence of the letter by the upper case letter.
私は今日これをやりたかったのですが、多くの文を含むことができる可変文字列「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を使っていたのでちょっと長いなと思ったので、スタックオーバーフローを調べてみました。似たような答えが1つあるのを除けば、これ以上単純なことはできないと思います...