簡體   English   中英

如何將NSString從CamelCase轉換為TitleCase,將“ playerName”轉換為“玩家名稱”?

[英]How do I convert an NSString from CamelCase to TitleCase, 'playerName' into 'Player Name'?

我正在尋找將字符串從駝峰格式轉換為標題大小寫格式的最簡單方法。

如何將“ playerName”更改為“ Player Name”?

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);

這是一個更簡單的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()

嘗試使用正則表達式替換

NSString *modified = [input stringByReplacingOccurrencesOfString:@"([a-z])([A-Z])"
                                                      withString:@"$1 $2"
                                                         options:NSRegularExpressionSearch
                                                           range:NSMakeRange(0, input.length)];

使用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"

雖然有點長,但是對於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;
}

我遇到了類似的問題,這里的答案幫助我創建了一個解決方案。 我有一個數組,其中包含要在UITableView中顯示的標簽列表,每行一個標簽。

我的問題是我從SOAP操作返回的XML中解析出了這些標簽,但我對字符串的格式一無所知。

首先,我將webstersx答案實現為一種方法。 這是偉大的,但一些唱片公司開始以一個大寫字母和一些地方的駱駝情況下(例如,一些字符串,其中exampleLabel和其他地方ExampleLabel 。因此,這意味着用大寫開頭的那些有插入串前面的空間。

我通過使用NSString的stringByTrimmingCharactersInSet修剪字符串的stringByTrimmingCharactersInSet和結尾的空格來解決此stringByTrimmingCharactersInSet

下一個問題是使用的任何縮寫,例如“ ID”或“ PNR Status”,其中顯示為“ ID”,而“ PNR Status”顯示為大寫字母,並且正確地在其中取了空格並在其前面插入了空格。

通過在我的新方法中實現類似於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狀態

如果有人需要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
}

嘗試更符合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)"
    }
}

我認為您可以使用一些正則表達式解決此問題。 看看這個類似的問題: iPhone開發人員:用空格和小寫字母替換NSString中的大寫字符

而技術上更短,效率更低

NSString *challengeString = @"playerName";
NSMutableString *rStr = [NSMutableString stringWithString:challengeString];

while ([rStr rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]].location != NSNotFound) {
    [rStr replaceCharactersInRange:[rStr rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]] withString:[[NSString stringWithFormat:@" %@", [rStr substringWithRange:[rStr rangeOfCharacterFromSet:[NSCharacterSet uppercaseLetterCharacterSet]]]] lowercaseString]];
}

NSLog(@"%@", rStr.capitalizedString);

不確定這是否比websterx短得多,但是我發現使用characterIsMember更容易閱讀和理解。 如果字符串以大寫字母開頭,還添加了一個長度檢查來固定空格。

NSString *str = @"PlayerNameHowAboutALongerString";
NSMutableString *str2 = [NSMutableString string];

for (NSInteger i=0; i<str.length; i++){
    unichar ch = [str characterAtIndex:i];
    if ( [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:ch]) {
        if (str2.length > 0 ) {
            [str2 appendString:@" "];
        }
    }
    [str2 appendString:[NSString stringWithCharacters:&ch length:1]];
}
NSLog(@"--%@--", str2.capitalizedString);

接受的答案對我不起作用,因為它沒有將首字母大寫,並且如果首字母已經大寫,則會在開頭添加多余的空格。 這是我的改進版本:

- (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;
}

這是Swift代碼(webstersx的目標c代碼),謝謝!

var str: NSMutableString = "iLoveSwiftCode"

        var str2: NSMutableString = NSMutableString()

        for var i:NSInteger = 0 ; i < str.length ; i++ {

            var ch:NSString = str.substringWithRange(NSMakeRange(i, 1))
            if(ch .rangeOfCharacterFromSet(NSCharacterSet.uppercaseLetterCharacterSet()).location != NSNotFound) {
            str2 .appendString(" ")
            }
            str2 .appendString(ch)
        }
        println("\(str2.capitalizedString)")

    }
NSString *input = @"playerName";
NSString *modified = [input stringByReplacingOccurrencesOfString:@"(?<!^)[A-Z]" withString:@" $0" options:NSRegularExpressionSearch range:NSMakeRange(0, input.length)].capitalizedString;

Swift 2.2下的另一個解決方案

extension String {
    var stringFromCamelCase:String {
        return (self as NSString).replacingOccurrences(
            of: "([a-z])([A-Z])",
            with: "$1 $2",
            options: CompareOptions.regularExpressionSearch,
            range: NSMakeRange(0, self.characters.count)
            ).uppercaseFirst
    }

    var uppercaseFirst: String {
        return String(characters.prefix(1)).uppercased() + String(characters.dropFirst()).lowercased()
    }
}

嘗試使用:

string.Split()

然后用大寫字母作為記號

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM