Преобразование строки верхнего регистра в регистр заголовка в Objective-C
Я создал следующий метод, который начинается с использования встроенного метода convertStringToTitleCase в NSString, но на самом деле он просто заглавными буквами первой буквы каждого слова. Я вижу, что в.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 ответа
Как отмечалось в комментариях, метод.NET, на который вы ссылаетесь, не делает "правильный" регистр заголовка (то есть, следуйте списку исключительных слов, которые следует оставить либо заглавными, либо строчными), поэтому -[NSString capitalizedString]
так же, как вы получите. Если вы хотите слова исключения, вам придется написать свой собственный метод (или найти кого-то еще, кто сделал, как поиск в Google для NSString "title case"
может быть).
Насколько "правильной" будет ваша заглавная буква, зависит от того, сколько исключительных слов вы готовы к ней добавить. Какую часть английского языка вы хотите поддержать? А как насчет других языков? Это также будет зависеть от того, насколько далеко вы продвинетесь в анализе границ слов - вы можете захотеть, чтобы "ТВ" оставался заглавными, независимо от того, находится ли он в кавычках, в конце предложения и т. Д., Но вы, вероятно, тоже не Я не хочу, чтобы "ты" вышел "Ты".
Если вы хотите обрабатывать слова исключений, ваш план многократного запуска replaceOccurrencesOfString...
будет медленнее, чем больше слов исключения у вас есть. (Кроме того, использование пробелов в строках поиска / замены означает, что вы не учитываете другие границы слов, которые вам могут понадобиться.)
Это может быть полезно рассмотреть NSRegularExpression
, поскольку регулярные выражения уже имеют достаточно четкие представления о границах падежей и слов. Если это не работает для вас, использование сканера для считывания входной строки при создании преобразованной выходной строки будет более эффективным, чем выполнение нескольких операций поиска / замены.
Хорошая однострочная (не общее решение, вероятно, очень неэффективное на огромных строках):
[[str lowercaseString] capitalizedString];
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
}
}