Swift aplica .uppercaseString solo a la primera letra de una cadena


232

Estoy tratando de hacer un sistema de autocorrección, y cuando un usuario escribe una palabra con una letra mayúscula, la autocorrección no funciona. Para solucionar esto, hice una copia de la cadena escrita, apliqué .lowercaseString y luego las comparé. Si la cadena está mal escrita, debería corregir la palabra. Sin embargo, entonces la palabra que reemplaza la palabra escrita es minúscula. Entonces necesito aplicar .uppercaseString solo a la primera letra. Originalmente pensé que podría usar

nameOfString[0]

pero esto aparentemente no funciona. ¿Cómo puedo poner la primera letra de la cadena en mayúscula y luego poder imprimir la cadena completa con la primera letra en mayúscula?

¡Gracias por cualquier ayuda!

Respuestas:


512

Incluyendo versiones mutantes y no mutantes que son consistentes con las pautas API.

Swift 3:

extension String {
    func capitalizingFirstLetter() -> String {
        let first = String(characters.prefix(1)).capitalized
        let other = String(characters.dropFirst())
        return first + other
    }

    mutating func capitalizeFirstLetter() {
        self = self.capitalizingFirstLetter()
    }
}

Swift 4:

extension String {
    func capitalizingFirstLetter() -> String {
      return prefix(1).uppercased() + self.lowercased().dropFirst()
    }

    mutating func capitalizeFirstLetter() {
      self = self.capitalizingFirstLetter()
    }
}

3
Solo una nota que .capitalizedStringya no funciona en Xcode 7 Beta 4. Las cadenas han cambiado un poco en Swift 2.0.
kakubei

2
@ Kirsteins: tienes razón, mi mal. Había olvidado importar Foundation sonrisa tímida
kakubei

3
@LoryLory Uso .uppercaseStringpara eso
Kirsteins

2
Este es el compañero de respuesta realmente efectivo ... Trabajando con Xcode 7.1.1 / Swift 2.1 .... Gracias :)
onCompletion

20
Es solo .capitalizedahora. Tenga en cuenta tambiéncapitalizedStringWith(_ locale:)
Raphael

152

Swift 5.1 o posterior

extension StringProtocol {
    var firstUppercased: String { prefix(1).uppercased() + dropFirst() }
    var firstCapitalized: String { prefix(1).capitalized + dropFirst() }
}

Swift 5

extension StringProtocol {
    var firstUppercased: String { return prefix(1).uppercased() + dropFirst() }
    var firstCapitalized: String { return prefix(1).capitalized + dropFirst() }
}

"Swift".first  // "S"
"Swift".last   // "t"
"hello world!!!".firstUppercased  // "Hello world!!!"

"DŽ".firstCapitalized   // "Dž"
"Dž".firstCapitalized   // "Dž"
"dž".firstCapitalized   // "Dž"

3
Buen trabajo. Edité el mío para pasar primero en minúscula y cambié el nombre a Proper.
ericgu

Me gusta la solución swift 2.1.1, pero cuando ejecuto mi aplicación y compruebo si hay fugas, muestra que está goteando.
Henny Lee

1
Acabo de crear un nuevo proyecto y parece que causa una pérdida de memoria cuando se usa junto con un UITextFieldobservador UITextFieldTextDidChangeNotification.
Henny Lee

@ Henry esto no tiene nada que ver con el código en sí. Si experimenta algún problema de rendimiento / memoria, debe informarlo a Apple.
Leo Dabus el

1
@LeoDabus, creo que depende de cuál hace que la intención del código sea más evidente. El literal de cadena vacío es quizás el mejor.
Nicolas Miari

84

Swift 3.0

para "Hello World"

nameOfString.capitalized

o para "HOLA MUNDO"

nameOfString.uppercased

3
Charlesism ya ha respondido con la versión Swift 3 hace dos meses ...
Eric Aya

11
Esto capitalizará el primer carácter de cada palabra de la Cadena y no solo la primera palabra.
Bocaxica

Devuelve: una copia en mayúscula de la cadena. func pública en mayúsculas () -> String Swift 3.0 o para "HOLA MUNDO" nameOfString.uppercased EN LUGAR DE ARRIBA nameOfString.uppercased ()
Azharhussain Shaikh

40

Swift 4.0

string.capitalized(with: nil)

o

string.capitalized

Sin embargo, esto pone en mayúscula la primera letra de cada palabra

Documentación de Apple:

Una cadena en mayúscula es una cadena con el primer carácter de cada palabra cambiado a su valor en mayúscula correspondiente, y todos los caracteres restantes configurados en sus valores en minúscula correspondientes. Una "palabra" es cualquier secuencia de caracteres delimitada por espacios, tabulaciones o terminadores de línea. No se considera alguna puntuación común delimitadora de palabras, por lo que esta propiedad generalmente no produce los resultados deseados para cadenas de varias palabras. Consulte el método getLineStart (_: end: contentsEnd: for :) para obtener información adicional.


1
No tengo idea de por qué las personas no son receptivas a esta respuesta. Si las personas quieren solo la primera palabra en mayúscula, pueden tomar la primera y capitalizarla más fácilmente con la propiedad en mayúscula.
ScottyBlades

1
Es importante destacar que "Capitalizado" es correcto para todos los caracteres Unicode, mientras que el uso de "mayúsculas" para el primer carácter no lo es.
gnasher729

23
extension String {
    func firstCharacterUpperCase() -> String? {
        let lowercaseString = self.lowercaseString

        return lowercaseString.stringByReplacingCharactersInRange(lowercaseString.startIndex...lowercaseString.startIndex, withString: String(lowercaseString[lowercaseString.startIndex]).uppercaseString)
    }
}

let x = "heLLo"
let m = x.firstCharacterUpperCase()

Para Swift 5:

extension String {
    func firstCharacterUpperCase() -> String? {
        guard !isEmpty else { return nil }
        let lowerCasedString = self.lowercased()
        return lowerCasedString.replacingCharacters(in: lowerCasedString.startIndex...lowerCasedString.startIndex, with: String(lowerCasedString[lowerCasedString.startIndex]).uppercased())
    }
}

Esta es la mejor respuesta de la OMI: es simple para todos los casos futuros.
Robert

No es necesario verificar si la cadena isEmptye inicializar una cadena para reemplazar tampoco. Simplemente puede desenvolver el primer carácter y en caso de que falle simplemente devuelva nil. Esto se puede simplificar comovar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Leo Dabus

17

Para el primer carácter en el uso de palabras .capitalizeden Swift y para uso de palabras completas.uppercased()


10

Swift 2.0 (línea única):

String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst())

1
Votado Sin embargo, esto supone que la cadena original es todo en minúsculas. He añadido .localizedLowercaseStringal final para que funcione con cadenas como: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi

4

Swift 3 (xcode 8.3.3)

Todos los primeros caracteres de cadena en mayúscula

let str = "your string"
let capStr = str.capitalized

//Your String

Todos los caracteres en mayúscula

let str = "your string"
let upStr = str.uppercased()

//YOUR STRING

Solo primer carácter en mayúscula de la cadena

 var str = "your string"
 let capStr = String(str.characters.prefix(1)).uppercased() + String(str.characters.dropFirst())

//Your string

Esto no capitalizará solo el primer carácter de una cadena
Rool Paap el


3

Estoy obteniendo el primer personaje duplicado con la solución de Kirsteins. Esto capitalizará el primer personaje, sin ver doble:

var s: String = "hello world"
s = prefix(s, 1).capitalizedString + suffix(s, countElements(s) - 1)

No sé si es más o menos eficiente, solo sé que me da el resultado deseado.


Podrías probar si poner en mayúscula el primer carácter cambia ese carácter, guardándolo en su propia constante y luego probando la igualdad con la nueva cadena 'mayúscula', y si son iguales, entonces ya tienes lo que quieres.
David H

Su publicación inspiró esta respuesta: ¡gracias !: func capitaizeFirstChar (var s: String) -> String {if s.isEmpty == false {let range = s.startIndex ... s.startIndex let original = s.substringWithRange (range) let capitalized = original.capitalizedString if original == capitalized {return s} s.replaceRange (range, with: capitalized)} return s}
David H

1
En las versiones más recientes de Swift, countElementses justo count.
George Poulos

3

Desde Swift 3 puedes usar fácilmente textField.autocapitalizationType = UITextAutocapitalizationType.sentences


3

Aquí hay una versión para Swift 5 que usa la API de propiedades escalares Unicode para rescatar si la primera letra ya está en mayúscula o no tiene una noción de mayúsculas y minúsculas:

extension String {
  func firstLetterUppercased() -> String {
    guard let first = first, first.isLowercase else { return self }
    return String(first).uppercased() + dropFirst()
  }
}

No es necesario inicializar una cadena con el primer carácter. return first.uppercased() + dropFirst()o un trazador de líneas(first?.uppercased() ?? "") + dropFirst()
Leo Dabus

2

Poner en mayúscula el primer carácter de la cadena.

extension String {
    var capitalizeFirst: String {
        if self.characters.count == 0 {
            return self

        return String(self[self.startIndex]).capitalized + String(self.characters.dropFirst())
    }
}

2

En Swift 3.0 (esto es un poco más rápido y seguro que la respuesta aceptada):

extension String {
    func firstCharacterUpperCase() -> String {
        if let firstCharacter = characters.first {
            return replacingCharacters(in: startIndex..<index(after: startIndex), with: String(firstCharacter).uppercased())
        }
        return ""
    }
}

nameOfString.capitalized no funcionará , capitalizará todas las palabras en la oración


1

Créditos a Leonardo Savio Dabus:

Me imagino que la mayoría de los casos de uso es obtener una carcasa adecuada:

import Foundation

extension String {

    var toProper:String {
        var result = lowercaseString
        result.replaceRange(startIndex...startIndex, with: String(self[startIndex]).capitalizedString)
        return result
    }
}

1

Mi solución:

func firstCharacterUppercaseString(string: String) -> String {
    var str = string as NSString
    let firstUppercaseCharacter = str.substringToIndex(1).uppercaseString
    let firstUppercaseCharacterString = str.stringByReplacingCharactersInRange(NSMakeRange(0, 1), withString: firstUppercaseCharacter)
    return firstUppercaseCharacterString
}

Esto no es puro rápido.
Abhishek Bedi

1

Al incorporar las respuestas anteriores, escribí una pequeña extensión que escribe en mayúscula la primera letra de cada palabra (porque eso es lo que estaba buscando y pensé que alguien más podría usarla).

Humildemente presento:

extension String {
    var wordCaps:String {
        let listOfWords:[String] = self.componentsSeparatedByString(" ")
        var returnString: String = ""
        for word in listOfWords {
            if word != "" {
                var capWord = word.lowercaseString as String
                capWord.replaceRange(startIndex...startIndex, with: String(capWord[capWord.startIndex]).uppercaseString)
                returnString = returnString + capWord + " "
            }
        }
        if returnString.hasSuffix(" ") {
            returnString.removeAtIndex(returnString.endIndex.predecessor())
        }
        return returnString
    }
}

1
Swift String tiene un método llamado capitalizedString. Si necesita aplicarlo a una serie de cadenas, consulte esta respuesta stackoverflow.com/a/28690655/2303865
Leo Dabus

1

Swift 4

func firstCharacterUpperCase() -> String {
        if self.count == 0 { return self }
        return prefix(1).uppercased() + dropFirst().lowercased()
    }

0

Esta es la forma en que lo hice en pequeños pasos, es similar a @Kirsteins.

func capitalizedPhrase(phrase:String) -> String {
    let firstCharIndex = advance(phrase.startIndex, 1)
    let firstChar = phrase.substringToIndex(firstCharIndex).uppercaseString
    let firstCharRange = phrase.startIndex..<firstCharIndex
    return phrase.stringByReplacingCharactersInRange(firstCharRange, withString: firstChar)
}

0
func helperCapitalizeFirstLetter(stringToBeCapd:String)->String{
    let capString = stringToBeCapd.substringFromIndex(stringToBeCapd.startIndex).capitalizedString
    return capString
}

También funciona, simplemente pasa tu cadena y recupera una en mayúscula.


0

Actualización de Swift 3

El replaceRangefunc es ahorareplaceSubrange

nameOfString.replaceSubrange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalized)

el método capitalizedString ha cambiado de nombre a capitalized
Rool Paap

0

Soy parcial a esta versión, que es una versión limpia de otra respuesta:

extension String {
  var capitalizedFirst: String {
    let characters = self.characters
    if let first = characters.first {
      return String(first).uppercased() + 
             String(characters.dropFirst())
    }
    return self
  }
}

Se esfuerza por ser más eficiente al evaluar solo los caracteres propios una vez, y luego usa formas consistentes para crear las subcadenas.


0

Swift 4 (Xcode 9.1)

extension String {
    var capEachWord: String {
        return self.split(separator: " ").map { word in
            return String([word.startIndex]).uppercased() + word.lowercased().dropFirst()
        }.joined(separator: " ")
    }
}

String ya tiene una propiedad llamada capitalizedexactamente para este propósito
Leo Dabus

0

Si desea poner en mayúscula cada palabra de cadena, puede usar esta extensión

Swift 4 Xcode 9.2

extension String {
    var wordUppercased: String {
        var aryOfWord = self.split(separator: " ")
        aryOfWord =  aryOfWord.map({String($0.first!).uppercased() + $0.dropFirst()})
        return aryOfWord.joined(separator: " ")
    }
}

Usado

print("simple text example".wordUppercased) //output:: "Simple Text Example"

2
simplemente use.capitalized
kakubei

0

Si su cadena es todo mayúsculas, el siguiente método funcionará

labelTitle.text = remarks?.lowercased().firstUppercased

Esta extensión te ayudará

extension StringProtocol {
    var firstUppercased: String {
        guard let first = first else { return "" }
        return String(first).uppercased() + dropFirst()
    }
}

1
simplemente use.capitalized
kakubei

@kakubei ¿Por qué haces un voto negativo? Este método es para el caso Sentance. Capitalizado hará cada primer carácter de la palabra a capital. Cadena de ejemplo: - (ESTO ES UN NIÑO) .capitalizeddevolverá (Esto es un niño) y este método devolverá (Esto es un niño) Ambos son diferentes. (Por favor, + ve voto negativo o eliminar)
Ashu

Tienes razón @ashu, mis disculpas. Sin embargo, no puedo votar hasta que edite la respuesta, así que tal vez solo haga una pequeña edición de espacios en blanco y la votaré. Lo siento de nuevo.
kakubei

No es necesario inicializar una cadena con el primer carácter. return first.uppercased() + dropFirst()o un regreso de línea(first?.uppercased() ?? "") + dropFirst()
Leo Dabus

0

Agregue esta línea en el método viewDidLoad ().

 txtFieldName.autocapitalizationType = UITextAutocapitalizationType.words

-1
extension String {
    var lowercased:String {
        var result = Array<Character>(self.characters);
        if let first = result.first { result[0] = Character(String(first).uppercaseString) }
        return String(result)
    }
}

-1

Para swift 5, puede hacer simplemente así:

yourString.firstUppercased

Muestra: "abc" -> "Abc"


No hay propiedad de primera calidad en Swift
Leo Dabus
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.