Swift applique .uppercaseString uniquement à la première lettre d'une chaîne


232

J'essaie de créer un système de correction automatique et lorsqu'un utilisateur tape un mot avec une majuscule, la correction automatique ne fonctionne pas. Afin de résoudre ce problème, j'ai fait une copie de la chaîne tapée, appliqué .lowercaseString, puis les ai comparés. Si la chaîne est en effet mal tapée, elle devrait corriger le mot. Cependant, le mot qui remplace le mot tapé est tout en minuscules. Je dois donc appliquer .uppercaseString à la première lettre uniquement. Au départ, je pensais pouvoir utiliser

nameOfString[0]

mais cela ne fonctionne apparemment pas. Comment puis-je obtenir la première lettre de la chaîne en majuscules, puis être en mesure d'imprimer la chaîne complète avec la première lettre en majuscule?

Merci pour toute aide!

Réponses:


512

Y compris les versions mutantes et non mutantes qui sont conformes aux directives de l'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
Juste une note qui .capitalizedStringne fonctionne plus dans Xcode 7 Beta 4. Les chaînes ont un peu changé dans Swift 2.0.
kakubei

2
@Kirsteins: vous avez raison, ma mauvaise. J'avais oublié d'importer un Foundation sourire penaud
kakubei

3
@LoryLory Use .uppercaseStringfor that
Kirsteins

2
C'est le compagnon de réponse vraiment efficace ... Travailler avec Xcode 7.1.1 / Swift 2.1 .... Merci :)
onCompletion

20
c'est juste .capitalizedmaintenant. Remarque égalementcapitalizedStringWith(_ locale:)
Raphael

152

Swift 5.1 ou version ultérieure

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
Bon travail. J'ai édité le mien pour passer en minuscules en premier et renommé Propre.
ericgu

J'aime la solution swift 2.1.1, mais lorsque j'exécute mon application et vérifie les fuites, cela montre que cela fuit.
Henny Lee

1
Je viens de créer un nouveau projet et il semble qu'il provoque une fuite de mémoire lorsqu'il est utilisé avec un UITextFieldobservateur UITextFieldTextDidChangeNotification.
Henny Lee

@Henry, cela n'a rien à voir avec le code lui-même. Si vous rencontrez un problème de performances / mémoire, vous devez le signaler à Apple.
Leo Dabus

1
@LeoDabus Je suppose que c'est à qui rend l'intention du code plus évidente. Le littéral de chaîne vide est peut-être le meilleur.
Nicolas Miari

84

Swift 3.0

pour "Hello World"

nameOfString.capitalized

ou pour "BONJOUR MONDE"

nameOfString.uppercased

3
Le Charlesisme a déjà répondu avec la version Swift 3 il y a deux mois ...
Eric Aya

11
Cela mettra en majuscule le premier caractère de chaque mot de la chaîne et pas seulement le premier mot.
Bocaxica

Renvoie: une copie majuscule de la chaîne. func public uppercased () -> String Swift 3.0 ou pour "HELLO WORLD" nameOfString.uppercased AU LIEU D'AU-DESSUS nameOfString.uppercased ()
Azharhussain Shaikh

40

Swift 4.0

string.capitalized(with: nil)

ou

string.capitalized

Cependant, cela met en majuscule la première lettre de chaque mot

Documentation d'Apple:

Une chaîne en majuscule est une chaîne dont le premier caractère de chaque mot est remplacé par sa valeur en majuscules correspondante, et tous les caractères restants définis sur leurs valeurs en minuscules correspondantes. Un «mot» est une séquence de caractères délimitée par des espaces, des tabulations ou des terminateurs de ligne. Certains mots communs délimitant la ponctuation ne sont pas pris en compte, de sorte que cette propriété ne produit généralement pas les résultats souhaités pour les chaînes de mots multiples. Voir la méthode getLineStart (_: end: contentsEnd: for :) pour plus d'informations.


1
Je n'ai aucune idée pourquoi les gens ne sont pas réceptifs à cette réponse. Si les gens veulent juste que le premier mot soit en majuscule, ils peuvent saisir le premier et le capitaliser plus facilement avec la propriété capitalisée.
ScottyBlades

1
Surtout, "Capitalisé" est correct pour tous les caractères Unicode, tandis que l'utilisation de "majuscule" pour le premier caractère ne l'est pas.
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()

Pour 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())
    }
}

C'est la meilleure réponse de l'OMI - elle reste simple pour tous les cas futurs.
Robert

Pas besoin de vérifier si la chaîne isEmptyet d'initialiser une chaîne à remplacer. Vous pouvez simplement déballer le premier caractère et en cas d'échec, renvoyez simplement zéro. Cela peut être simplifié commevar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Leo Dabus

17

Pour le premier caractère du mot à utiliser .capitalizedrapidement et pour le mot entier.uppercased()


10

Swift 2.0 (une seule ligne):

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

1
A voté. Cependant, cela suppose que la chaîne d'origine est entièrement en minuscules. J'ai ajouté .localizedLowercaseStringà la fin pour le faire fonctionner avec des chaînes comme: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi

4

Swift 3 (xcode 8.3.3)

Majuscules tous les premiers caractères de la chaîne

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

//Your String

Majuscules tous les caractères

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

//YOUR STRING

Majuscule uniquement le premier caractère de la chaîne

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

//Your string

Cela ne mettra pas en majuscule uniquement le premier caractère d'une chaîne
Rool Paap


3

J'obtiens le premier caractère dupliqué avec la solution de Kirsteins. Cela mettra en majuscule le premier caractère, sans voir double:

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

Je ne sais pas si c'est plus ou moins efficace, je sais juste que ça me donne le résultat souhaité.


Vous pouvez tester si la mise en majuscule du premier caractère change ce caractère - en l'enregistrant dans sa propre constante puis en testant l'égalité avec la nouvelle chaîne `` en majuscule '', et si elles sont identiques, vous avez déjà ce que vous voulez.
David H

Votre message a inspiré cette réponse - merci!: 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
Dans les nouvelles versions de Swift, countElementsc'est juste count.
George Poulos

3

Depuis Swift 3, vous pouvez facilement utiliser textField.autocapitalizationType = UITextAutocapitalizationType.sentences


3

Voici une version pour Swift 5 qui utilise l' API des propriétés scalaires Unicode pour renflouer si la première lettre est déjà en majuscule ou n'a pas de notion de casse:

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

Pas besoin d'initialiser une chaîne avec le premier caractère. return first.uppercased() + dropFirst()ou un paquebot(first?.uppercased() ?? "") + dropFirst()
Leo Dabus

2

Mettre en majuscule le premier caractère de la chaîne

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

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

2

Dans Swift 3.0 (c'est un peu plus rapide et plus sûr que la réponse acceptée):

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

nameOfString.capitalized ne fonctionnera pas , il mettra en majuscule tous les mots de la phrase


1

Crédits à Leonardo Savio Dabus:

J'imagine que la plupart des cas d'utilisation consistent à obtenir un boîtier approprié:

import Foundation

extension String {

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

1

Ma solution:

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
}

Ce n'est pas purement rapide.
Abhishek Bedi

1

En incorporant les réponses ci-dessus, j'ai écrit une petite extension qui met en majuscule la première lettre de chaque mot (parce que c'est ce que je cherchais et j'ai pensé que quelqu'un d'autre pourrait l'utiliser).

Je soumets humblement:

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 a une méthode appelée capitalizedString. Si vous devez l'appliquer à un tableau de chaînes, vérifiez cette réponse 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

Voici la façon dont je l'ai fait par petites étapes, c'est similaire à @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
}

Fonctionne également, passez simplement votre chaîne et récupérez-en une en majuscule.


0

Mise à jour Swift 3

Le replaceRangefunc est maintenantreplaceSubrange

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

la méthode capitalizedString a été renommée en capitalisé
Rool Paap

0

Je suis partial pour cette version, qui est une version nettoyée d'une autre réponse:

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

Il s'efforce d'être plus efficace en n'évaluant les self.characters qu'une seule fois, puis utilise des formulaires cohérents pour créer les sous-chaînes.


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 a déjà une propriété appelée capitalizedexactement à cet effet
Leo Dabus

0

Si vous souhaitez mettre en majuscule chaque mot de chaîne, vous pouvez utiliser cette extension

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

Utilisé

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

2
utilisez simplement.capitalized
kakubei

0

Si votre chaîne est entièrement en majuscules, la méthode ci-dessous fonctionnera

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

Cette extension vous aidera

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

1
utilisez simplement.capitalized
kakubei

@kakubei Pourquoi vous votez négativement. Cette méthode concerne le cas Sentance. Les majuscules feront tous les premiers caractères du mot en majuscules. Exemple de chaîne: - (CECI EST UN GARÇON) .capitalizedretournera (Ceci est un garçon) et cette méthode retournera (Ceci est un garçon) Les deux sont différents. (Veuillez faire un vote positif ou supprimer le négatif)
Ashu

Vous avez raison @ashu, mes excuses. Cependant, je ne peux pas voter en amont jusqu'à ce que vous modifiiez la réponse, alors faites peut-être juste un petit espace blanc et je le voterai. Encore pardon.
kakubei

Pas besoin d'initialiser une chaîne avec le premier caractère. return first.uppercased() + dropFirst()ou un retour de ligne(first?.uppercased() ?? "") + dropFirst()
Leo Dabus

0

Ajoutez cette ligne dans la méthode 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

Pour swift 5, vous pouvez simplement faire comme ça:

yourString.firstUppercased

Exemple: "abc" -> "Abc"


Il n'y a pas de première propriété en majuscule à Swift
Leo Dabus
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.