2

我创建了以下方法,首先在 NSString 上使用内置的 convertStringToTitleCase 方法,但它实际上只是将每个单词的第一个字母大写。我在 .NET 中看到有一个 TextInfo.ToTitleCase 方法,它尝试了我想用 Objective-C 做的事情,但也达不到要求。

http://msdn.microsoft.com/en-us/library/system.globalization.textinfo.totitlecase.aspx

我写的开始方法如下。您将如何正确处理大写字符串的大小写?将单词数据库转换为所有大写/小写有帮助吗?

- (NSString *)convertStringToTitleCase:(NSString *)str {
    NSMutableString *convertedStr = [NSMutableString stringWithString:[str capitalizedString]];

    NSRange range = NSMakeRange(0, convertedStr.length);

    // a list of words to always make lowercase could be placed here
    [convertedStr replaceOccurrencesOfString:@" De " 
                                  withString:@" de " 
                                     options:NSLiteralSearch 
                                       range:range];

    // a list of words to always make uppercase could be placed here
    [convertedStr replaceOccurrencesOfString:@" Tv " 
                                  withString:@" TV " 
                                     options:NSLiteralSearch 
                                       range:range];

    return convertedStr;
}
4

3 回答 3

6

如评论中所述,您引用的 .NET 方法不使用“正确”的标题大小写(即,遵循以全大写或全小写形式保留的异常词列表),因此-[NSString capitalizedString]与你会得到。如果您想要异常词,则必须编写自己的方法(或找到其他人,如谷歌搜索NSString "title case"可能)。

你的标题大小写有多“合适”取决于你愿意抛出多少异常词。您希望它支持多少英语?其他语言呢?它还取决于您在分析单词边界方面走了多远——您可能希望“TV”保持全大写,无论它是否在引号中、句尾等,但您也可能不这样做不想让“you've”出现“You'Ve”。

如果你想处理异常词,你的重复运行计划replaceOccurrencesOfString...会越慢,你的异常词越多。(此外,在搜索/替换字符串中使用空格意味着您没有考虑您可能想要的其他单词边界。)

考虑 可能很有用NSRegularExpression,因为正则表达式已经具有相当健壮的大小写和单词边界概念。如果这对您不起作用,则使用扫描仪读取输入字符串同时生成转换后的输出字符串将比运行多个搜索/替换操作更有效。

于 2012-04-16T20:03:37.583 回答
6

一个不错的单线(不是通用解决方案,在大字符串上可能效率很低):

[[str lowercaseString] capitalizedString];
于 2015-06-02T02:33:39.637 回答
1
extension String {

    /**
      Get the title case string.
     */
    var titleCase: String {
        get {
            return getTitleCaseString()
        }
    }

    // MARK: Private methods.

    /**
     Get title case string.

     - returns: The title case string regarding the lowercase words.
     */
    private func getTitleCaseString() -> String {
        struct Holder {
            static let lowercaseWords = ["a", "an", "and", "at", "but", "by", "else", "for",
                                         "from", "if", "in", "into", "is", "nor", "of", "off",
                                         "on", "or", "out", "the", "to", "via", "vs", "with"]
        }
        return replaceToLowercaseAllOccurrencesOfWords(Holder.lowercaseWords).capitalizeFirst
    }

    /**
     Replace to lowercase all occurrences of lowercase words.

     - parameter lowercaseWords: The lowercase words to replace.

     - returns: String with all occurrences replace to the lowercase words.
     */
    private func replaceToLowercaseAllOccurrencesOfWords(lowercaseWords: [String]) -> String {
        let capitalizedSelf = NSMutableString(string: self.capitalizedString)
        for word in lowercaseWords {
            if let lowercaseWordRegex = try? NSRegularExpression(pattern: "\\b\(word)\\b", options: .CaseInsensitive) {
                lowercaseWordRegex.replaceMatchesInString(capitalizedSelf,
                                                          options: NSMatchingOptions(),
                                                          range: NSMakeRange(0, capitalizedSelf.length),
                                                          withTemplate: word)
            }
        }
        return capitalizedSelf as String
    }

/**
     Capitalize first char.
     */
    private var capitalizeFirst: String {
        if isEmpty { return "" }
        var result = self
        result.replaceRange(startIndex...startIndex, with: String(self[startIndex]).uppercaseString)
        return result
    }

}
于 2016-06-06T12:24:58.080 回答