Как мне преобразовать NSString из CamelCase в TitleCase, «playerName» в «Имя игрока»? - PullRequest
13 голосов
/ 04 января 2011

Я ищу самый простой способ преобразовать строку из формата Camelback в формат Case Case.

Как мне поменять 'playerName' на 'Player Name'?

Ответы [ 16 ]

21 голосов
/ 21 марта 2013
NSString *str = @"playerName";
NSMutableString *str2 = [NSMutableString string];

for (NSInteger i=0; i<str.length; i++){
    NSString *ch = [str substringWithRange:NSMakeRange(i, 1)];
    if ([ch rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]].location != NSNotFound) {
        [str2 appendString:@" "];
    }
    [str2 appendString:ch];
}
NSLog(@"%@", str2.capitalizedString);
15 голосов
/ 24 августа 2015

Вот более простая версия Swift.Я поместил его в расширение

extension String {

    func stringFromCamelCase() -> String {
        var string = self
        string = string.stringByReplacingOccurrencesOfString("([a-z])([A-Z])", withString: "$1 $2", options: NSStringCompareOptions.RegularExpressionSearch, range: Range<String.Index>(start: string.startIndex, end: string.endIndex))
        string.replaceRange(startIndex...startIndex, with: String(self[startIndex]).capitalizedString)
        return string
    }

}

Использование:

var str = "helloWorld"
str = str.stringFromCamelCase()
11 голосов
/ 14 августа 2013

Попробуйте использовать регулярное выражение заменить

NSString *modified = [input stringByReplacingOccurrencesOfString:@"([a-z])([A-Z])"
                                                      withString:@"$1 $2"
                                                         options:NSRegularExpressionSearch
                                                           range:NSMakeRange(0, input.length)];
5 голосов
/ 06 августа 2012

Немного короче, используя NSCharacterSet:

__block NSString *str = @"myVerySpecialPlayerName" ;

// split at uppercase letters
NSArray *splitString = [str componentsSeparatedByCharactersInSet:
     [NSCharacterSet uppercaseLetterCharacterSet]] ;

// get the uppercase letters
NSArray *upperCaseLetters = [str componentsSeparatedByCharactersInSet:
     [[NSCharacterSet uppercaseLetterCharacterSet] invertedSet]] ;

// join with two spaces
str = [splitString componentsJoinedByString:@"  "] ;
__block NSInteger offset = 0 ;

// replace each second space with the missing uppercase letter
[upperCaseLetters enumerateObjectsUsingBlock:^(NSString *character, NSUInteger idx, BOOL *stop) {
    if( [character length] > 0 ) {
        str = [str stringByReplacingCharactersInRange:NSMakeRange(idx+offset+1, 1) withString:character] ;
        offset += 2 ;
    }
}] ;

// & capitalize the first one
str = [str capitalizedString] ;

NSLog(@"%@", str) ; // "My Very Special Player Name"
2 голосов
/ 13 декабря 2016

Попытка быть более совместимой с Unicode

extension String {
    func camelCaseToTitleCase() -> String {
        return unicodeScalars.map(replaceCaptialsWithSpacePlusCapital).joined().capitalized
    }
    private func replaceCaptialsWithSpacePlusCapital(unichar: UnicodeScalar) -> String {
        if CharacterSet.uppercaseLetters.contains(unichar) {
            return " \(unichar)"
        }
        return "\(unichar)"
    }
}
2 голосов
/ 11 марта 2015

Если кому-то нужна версия Swift:

func camelCaseToTitleCase(s: NSString) -> String {
    var newString = ""
    if s.length > 0 {
        newString = s.substringToIndex(1).uppercaseString
        for i in 1..<s.length {
            let char = s.characterAtIndex(i)
            if NSCharacterSet.uppercaseLetterCharacterSet().characterIsMember(char) {
                newString += " "
            }
            newString += s.substringWithRange(NSRange(location: i, length: 1))
        }
    }
    return newString
}
2 голосов
/ 10 октября 2013

У меня была похожая проблема, ответы здесь помогли мне найти решение.У меня был массив, в котором был список меток, которые я хотел отобразить в UITableView, по одной метке на строку.

Моя проблема заключалась в том, что я разобрал эти метки из XML, возвращенного действием SOAP, и я понятия не имелповерх формата строк.

Сначала я реализовал ответ webstersx в метод.Это было замечательно, но некоторые из этих ярлыков начинались с заглавной буквы, а некоторые - в случае верблюда (например, в некоторых строках, где exampleLabel, а в других - ExampleLabel. Таким образом, это означало, что у тех, кто начинался с заглавной буквы, было вставлено пространство передstring.

Я преодолел это, обрезав пробелы в начале и конце строки, используя stringByTrimmingCharactersInSet.

для NSString. Следующей проблемой были любые используемые сокращения, такие как "ID" или "PNRСтатус ", где отображаются как" ID "и" Статус PNR "как заглавные буквы, где, и совершенно справедливо, поднято и вставлен пробел перед ним.

Я преодолел эту проблему, применяя регулярное выражение, подобноена ответ emdog4 в мой новый метод.

Вот мое законченное решение:

- (NSString *)formatLabel:(NSString *)label
{
    NSMutableString *str2 = [NSMutableString string];

    for (NSInteger i=0; i<label.length; i++){
        NSString *ch = [label substringWithRange:NSMakeRange(i, 1)];
        if ([ch rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]].location != NSNotFound) {
            [str2 appendString:@" "];
        }
        [str2 appendString:ch];
    }
    NSString * formattedString = [str2 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]].capitalizedString;

    formattedString = [formattedString stringByReplacingOccurrencesOfString:@"([A-Z]) (?![A-Z][a-z])" withString:@"$1" options:NSRegularExpressionSearch range:NSMakeRange(0, formattedString.length)];

    return formattedString;
}

Затем я просто вызываю что-то вроде этого, например, которое вернет мою красиво отформатированную строку:

NSString * formattedLabel = [self formatLabel:@"PNRStatus"];
NSLog(@"Formatted Label: %@", formattedLabel);

Будет выводить:

2013-10-10 10: 44: 39.888 Тестовый проект [28296: a0b] Отформатированная метка: PNR Status

2 голосов
/ 05 августа 2012

Хотя и немного долго, но эта категория для NSString должна сработать.Он прошел все мои тесты:

- (NSString *)splitOnCapital
{
  // Make a index of uppercase characters
  NSRange upcaseRange = NSMakeRange('A', 26);
  NSIndexSet *upcaseSet = [NSIndexSet indexSetWithIndexesInRange:upcaseRange];

  // Split our camecase word
  NSMutableString *result = [NSMutableString string];
  NSMutableString *oneWord = [NSMutableString string];
  for (int i = 0; i < self.length; i++) {
    char oneChar = [self characterAtIndex:i];
    if ([upcaseSet containsIndex:oneChar]) {
      // Found a uppercase char, now save previous word
      if (result.length == 0) {
        // First word, no space in beginning
        [result appendFormat:@"%@", [oneWord capitalizedString]];
      }else {
        [result appendFormat:@" %@", oneWord];
      }

      // Clear previous word for new word
      oneWord = [NSMutableString string];
    }

    [oneWord appendFormat:@"%c", oneChar];
  }

  // Add last word
  if (oneWord.length > 0) {
    [result appendFormat:@" %@", oneWord];
  }

  return result;
}
2 голосов
/ 04 января 2011

Я думаю, что вы можете решить эту проблему с помощью некоторых регулярных выражений. Проверьте этот похожий вопрос: iPhone dev: заменить заглавные буквы в строке NSSt пробелом и нижним регистром

1 голос
/ 13 февраля 2014

Принятый ответ не сработал для меня, потому что он не с заглавной буквы первой буквы, а если первая буква уже заглавная, он добавляет посторонний пробел в начале Вот моя улучшенная версия:

- (NSString *)titleFromCamelCaseString:(NSString *)input
{
    NSMutableString *output = [NSMutableString string];
    [output appendString:[[input substringToIndex:1] uppercaseString]];
    for (NSUInteger i = 1; i < [input length]; i++)
    {
        unichar character = [input characterAtIndex:i];
        if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:character])
        {
            [output appendString:@" "];
        }
        [output appendFormat:@"%C", character];
    }
    return output;
}
...