在Objective-C中将大写字符串转换为标题大小写

时间:2012-04-16 19:02:42

标签: objective-c string casing

我创建了以下方法,该方法首先使用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;
}

3 个答案:

答案 0 :(得分:6)

如注释中所述,您引用的.NET方法不执行“正确”标题大小写(即,按照全部大写或全小写的方式保留异常单词列表),因此{ {1}}与您将获得的相同。如果你想要异常单词,你必须编写自己的方法(或找到其他人,可能会google search for NSString "title case")。

你的标题框的“正确”程度取决于你愿意抛出多少个异常单词。你想要它支持多少英语?其他语言怎么样?它还取决于你在分析单词界限方面走得多远 - 你可能希望“电视”保持全部上限,无论它是在引号中,在一个句子的结尾处等等,但你可能也不喜欢我希望“你有”出来“你'”。

如果您想处理异常字,那么重复运行-[NSString capitalizedString]的计划会越慢,您拥有的异常字数就越多。 (另外,在搜索/替换字符串中使用空格意味着您不会考虑其他可能需要的字边界。)

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

答案 1 :(得分:6)

一个很好的单行(不是一般解决方案,可能对大字符串效率非常低):

[[str lowercaseString] capitalizedString];

答案 2 :(得分: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
    }

}