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!

Un gars
la source

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()
    }
}
Kirsteins
la source
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ž"
Leo Dabus
la source
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
Maselko
la source
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.

sam k
la source
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())
    }
}
user2260304
la source
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()

DURGESH
la source
10

Swift 2.0 (une seule ligne):

String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst())
Phil
la source
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
oscar castellon
la source
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é.

Marc Fearby
la source
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

Yura
la source
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()
  }
}
Adam Sharp
la source
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())
    }
}
user3699466
la source
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

pierre23
la source
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
    }
}
ericgu
la source
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
}
Nazariy Vlizlo
la source
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
    }
}
Mat
la source
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()
    }
Gayratjon
la source
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)
}
guptron
la source
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.

Dan Leonard
la source
0

Mise à jour Swift 3

Le replaceRangefunc est maintenantreplaceSubrange

nameOfString.replaceSubrange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalized)
Brendt Bly
la source
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.

Patrick Beard
la source
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: " ")
    }
}
Daniel R
la source
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"
Shilpriya
la source
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()
    }
}
Ashu
la source
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
Pranit
la source
-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)
    }
}
john07
la source
-1

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

yourString.firstUppercased

Exemple: "abc" -> "Abc"

Hula
la source
Il n'y a pas de première propriété en majuscule à Swift
Leo Dabus