2011-09-06 17 views
7

¿Cuál sería la forma más eficiente de convertir una cadena como "ThisStringIsJoined" a "This String Is Joined" en objetivo-c?Insertar o dividir cadena en letras mayúsculas objetivo-c

Recibo cadenas como esta de un servicio web que está fuera de mi control y me gustaría presentar los datos al usuario, por lo que me gustaría arreglarlo un poco agregando espacios delante de cada palabra en mayúscula. Las cadenas siempre se formatean con cada palabra que comienza en una letra mayúscula.

Soy bastante nuevo en Objective-C, así que no puedo entenderlo.

Gracias

+0

duplicado posible: http: // stackoverflow.com/questions/1588205/how-to-split-a-string-with-the-uppercase-character-in-iphone – 0x8badf00d

Respuesta

34

Una forma de lograr esto es la siguiente:

NSString *string = @"ThisStringIsJoined"; 
NSRegularExpression *regexp = [NSRegularExpression 
    regularExpressionWithPattern:@"([a-z])([A-Z])" 
    options:0 
    error:NULL]; 
NSString *newString = [regexp 
    stringByReplacingMatchesInString:string 
    options:0 
    range:NSMakeRange(0, string.length) 
    withTemplate:@"$1 $2"]; 
NSLog(@"Changed '%@' -> '%@'", string, newString); 

La salida en este caso sería:

'ThisStringIsJoined' -> 'This String Is Joined' 

Es posible que desee modificar la expresión regular que es el propietario necesidades . Es posible que desee convertir esto en una categoría en NSString.

+0

Gracias, funciona genial – Craigt

+1

@aLevelOfIndirection Gracias, eso funcionó como un encanto – death7eater

+0

¿Qué puedo añadir? aquí para excluir la adición de espacio entre acrónimos? como HelloHTMLGoodbye debe producir Hello HTML Goodbye? – userx

-1

Usted podría intentar hacer una nueva cadena que es una copia minúscula de la cadena original. Luego compare las dos cadenas e inserte espacios donde los caracteres sean diferentes.

Utilice el método NSString para pasar a minúsculas.

- (NSString *)lowercaseString 
9

NSRegularExpression s son el camino a seguir, pero como curiosidades, NSCharacterSet también pueden ser útiles:

- (NSString *)splitString:(NSString *)inputString { 

    int index = 1; 
    NSMutableString* mutableInputString = [NSMutableString stringWithString:inputString]; 

    while (index < mutableInputString.length) { 

     if ([[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:[mutableInputString characterAtIndex:index]]) { 
      [mutableInputString insertString:@" " atIndex:index]; 
      index++; 
     } 
     index++; 
    } 

    return [NSString stringWithString:mutableInputString]; 
} 
+0

¡Excelente solución! – user523234

+0

¿Alguien verificó si la solución de RegularExpression es más lenta que esta? – Daniel

1

Aquí es una categoría en NSString que va a hacer lo que quiere. Esto manejará letras que no sean ASCII. También dividirá "IDidAGoodThing" correctamente.

@implementation NSString (SeparateCapitalizedWords) 

-(NSString*)stringBySeparatingCapitalizedWords 
{ 
    static NSRegularExpression * __regex ; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     NSError * error = nil ; 
     __regex = [ NSRegularExpression regularExpressionWithPattern:@"[\\p{Uppercase Letter}]" options:0 error:&error ] ; 
     if (error) { @throw error ; } 
    }); 

    NSString * result = [ __regex stringByReplacingMatchesInString:self options:0 range:(NSRange){ 1, self.length - 1 } withTemplate:@" $0" ] ; 
    return result ; 
} 

@end 
1

Aquí está Swift Code (código objetivo c de webstersx), ¡Gracias!

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

    } 

Salida: Amo Código Swift

+0

si la cadena de entrada comienza con un carácter en mayúscula, esto agregará un espacio inicial. – alexkent

0

Para cualquier persona que vino aquí en busca de la pregunta similar contestado en Swift: Tal vez un limpiador (añadiendo a la respuesta de Sankalp), y más 'Swifty "enfoque:

func addSpaces(to givenString: String) -> String{ 
    var string = givenString 

    //indexOffset is needed because each time replaceSubrange is called, the resulting count is incremented by one (owing to the fact that a space is added to every capitalised letter) 
    var indexOffset = 0 
    for (index, character) in string.characters.enumerated(){ 
     let stringCharacter = String(character) 

     //Evaluates to true if the character is a capital letter 
     if stringCharacter.lowercased() != stringCharacter{ 
      guard index != 0 else { continue } //"ILoveSwift" should not turn into " I Love Swift" 
      let stringIndex = string.index(string.startIndex, offsetBy: index + indexOffset) 
      let endStringIndex = string.index(string.startIndex, offsetBy: index + 1 + indexOffset) 
      let range = stringIndex..<endStringIndex 
      indexOffset += 1 
      string.replaceSubrange(range, with: " \(stringCharacter)") 
     } 
    } 
    return string 
} 

llamar a la función de este modo:

var string = "iLoveSwiftCode" 
addSpaces(to: string) 
//Result: string = "i Love Swift Code" 

Alternativamente, si lo prefiere extensiones:

extension String{ 
    mutating func seperatedWithSpaces(){ 
     //indexOffset is needed because each time replaceSubrange is called, the resulting count is incremented by one (owing to the fact that a space is added to every capitalised letter) 
     var indexOffset = 0 
     for (index, character) in characters.enumerated(){ 
      let stringCharacter = String(character) 

      if stringCharacter.lowercased() != stringCharacter{ 
       guard index != 0 else { continue } //"ILoveSwift" should not turn into " I Love Swift" 
       let stringIndex = self.index(self.startIndex, offsetBy: index + indexOffset) 
       let endStringIndex = self.index(self.startIndex, offsetBy: index + 1 + indexOffset) 
       let range = stringIndex..<endStringIndex 
       indexOffset += 1 
       self.replaceSubrange(range, with: " \(stringCharacter)") 
      } 
     } 
    } 
} 

llamar al método de una cadena:

var string = "iLoveSwiftCode" 
string.seperatedWithSpaces() 
//Result: string = "i Love Swift Code" 
Cuestiones relacionadas