Swift aplica .uppercaseString apenas à primeira letra de uma sequência

232

Estou tentando criar um sistema de correção automática e, quando um usuário digita uma palavra com letra maiúscula, a correção automática não funciona. Para corrigir isso, fiz uma cópia da string digitada, apliquei .lowercaseString e as comparei. Se a string for realmente digitada incorretamente, deve corrigir a palavra. No entanto, a palavra que substitui a palavra digitada é minúscula. Portanto, preciso aplicar .uppercaseString apenas à primeira letra. Eu originalmente pensei que poderia usar

nameOfString[0]

mas isso aparentemente não funciona. Como posso colocar a primeira letra da string em maiúsculas e poder imprimir a string completa com a primeira letra maiúscula?

Obrigado por qualquer ajuda!

SomeGuy
fonte

Respostas:

512

Incluindo versões mutantes e não mutantes que são consistentes com as diretrizes da 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
fonte
3
Apenas uma observação que .capitalizedStringnão funciona mais no Xcode 7 Beta 4. As strings mudaram um pouco no Swift 2.0.
kakubei
2
@ Kirsteins: você está certo, meu mal. Eu tinha esquecido de importar Foundation sorriso tímido
kakubei
3
@LoryLory Use .uppercaseStringfor that
Kirsteins
2
Esta é a resposta realmente eficaz, companheiro ... Trabalhando com o Xcode 7.1.1 / Swift 2.1 .... Obrigado :)
onCompletion
20
é só .capitalizedagora. Note tambémcapitalizedStringWith(_ locale:)
Raphael
152

Swift 5.1 ou 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ž"
Leo Dabus
fonte
3
Bom trabalho. Eu editei o meu para passar em minúsculas primeiro e renomei para Proper.
ericgu
Gosto da rápida solução 2.1.1, mas quando executo o aplicativo e verifico se há vazamentos, está mostrando que está vazando.
quer
1
Acabei de criar um novo projeto e parece que causa um vazamento de memória quando isso é usado junto com um UITextFieldobservador para UITextFieldTextDidChangeNotification.
Henny Lee
@ Henry, isso não tem nada a ver com o próprio código. Se você tiver algum problema de desempenho / memória, informe-o à Apple.
Leo Dabus
1
@LeoDabus Eu acho que se resume a Qual deles torna a intenção do código mais evidente. O literal da string vazia talvez seja o melhor.
Nicolas Miari 22/09
84

Swift 3.0

para "Olá Mundo"

nameOfString.capitalized

ou para "OLÁ MUNDO"

nameOfString.uppercased
Maselko
fonte
3
O Charlesism já respondeu com a versão Swift 3 há dois meses ...
Eric Aya
11
Isso colocará em maiúscula o primeiro caractere de cada palavra da String e não apenas a primeira palavra.
Bocaxica
Retorna: uma cópia em maiúscula da sequência. func pública uppercased () -> string Swift 3.0 ou para "OLÁ MUNDO" nameOfString.uppercased EM VEZ DE ACIMA nameOfString.uppercased ()
Azharhussain Shaikh
40

Swift 4.0

string.capitalized(with: nil)

ou

string.capitalized

No entanto, isso coloca em maiúscula a primeira letra de cada palavra

Documentação da Apple:

Uma string em maiúscula é uma string com o primeiro caractere em cada palavra alterado para seu valor em maiúsculas correspondente e todos os caracteres restantes configurados para seus valores em minúsculas correspondentes. Uma "palavra" é qualquer sequência de caracteres delimitada por espaços, tabulações ou terminadores de linha. Algumas pontuações comuns de delimitação de palavras não são consideradas; portanto, essa propriedade geralmente não produz os resultados desejados para sequências de várias palavras. Consulte o método getLineStart (_: end: contentsEnd: for :) para obter informações adicionais.

sam k
fonte
1
Não tenho ideia de por que as pessoas não são receptivas a essa resposta. Se as pessoas querem apenas a primeira palavra em maiúscula, podem agarrá-la e capitalizá-la mais facilmente com a propriedade capitalizada.
ScottyBlades
1
É importante ressaltar que "Capitalizado" está correto para todos os caracteres Unicode, enquanto o uso de "maiúsculas" para o primeiro caractere não.
precisa saber é o seguinte
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 o 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
fonte
Esta é a melhor resposta para IMO - simplifica para todos os casos futuros.
Robert
Não há necessidade de verificar se a string isEmptye inicializar uma string para substituir também. Você pode simplesmente desembrulhar o primeiro caractere e, caso falhe, retorne nulo. Isso pode ser simplificado comovar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Leo Dabus
17

Para o primeiro caractere no uso de palavras .capitalizedem swift e para uso de palavras inteiras.uppercased()

DURGESH
fonte
10

Swift 2.0 (linha única):

String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst())
Phil
fonte
1
Votado. No entanto, isso pressupõe que a string original esteja em minúscula. Eu adicionei .localizedLowercaseStringno final para fazê-lo funcionar com strings como: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi 6/09/16
4

Swift 3 (xcode 8.3.3)

Maiúsculas todos os primeiros caracteres da string

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

//Your String

Todos os caracteres em maiúsculas

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

//YOUR STRING

Apenas o primeiro caractere da string em maiúsculas

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

//Your string
oscar castellon
fonte
Isso não vai capitalizar apenas o primeiro caractere de uma string
Rool Paap
3

Estou duplicando o primeiro personagem com a solução de Kirsteins. Isso colocará em maiúscula o primeiro caractere, sem ver o dobro:

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

Não sei se é mais ou menos eficiente, só sei que isso me dá o resultado desejado.

Marc Fearby
fonte
Você pode testar se a capitalização do primeiro caractere altera esse caractere - salvando-o em sua própria constante e testando a igualdade com a nova string 'capitalizada', e se eles são iguais, você já tem o que deseja.
23715 David H
Sua postagem inspirou esta resposta - obrigado !: func capitaizeFirstChar (var s: String) -> String {if s.isEmpty == false {let range = s.startIndex ... s.startIndex deixe original = s.substringWithRange (range) deixar capitalizado = original.capitalizedString se originais == capitalizado {s} de retorno s.replaceRange (gama, com: capitalizado)} retorno s}
David H
1
Nas versões mais recentes do Swift, countElementsé justo count.
George Poulos
3

No Swift 3 você pode usar facilmente textField.autocapitalizationType = UITextAutocapitalizationType.sentences

Yura
fonte
3

Aqui está uma versão do Swift 5 que usa a API de propriedades escalares Unicode para resgatar se a primeira letra já estiver em maiúscula ou se não houver uma noção de caso:

extension String {
  func firstLetterUppercased() -> String {
    guard let first = first, first.isLowercase else { return self }
    return String(first).uppercased() + dropFirst()
  }
}
Adam Sharp
fonte
Não há necessidade de inicializar uma String com o primeiro caractere. return first.uppercased() + dropFirst()ou um forro(first?.uppercased() ?? "") + dropFirst()
Leo Dabus
2

Coloque em maiúscula o primeiro caractere na sequência

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

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

No Swift 3.0 (isso é um pouco mais rápido e seguro do que a resposta aceita):

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

nameOfString.capitalized não funciona , coloca em maiúscula todas as palavras na frase

pierre23
fonte
1

Créditos a Leonardo Savio Dabus:

Eu imagino que a maioria dos casos de uso é obter a embalagem adequada:

import Foundation

extension String {

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

Minha solução:

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
fonte
Isso não é puro rápido.
Abhishek Bedi
1

Incorporando as respostas acima, escrevi uma pequena extensão que maiúscula a primeira letra de cada palavra (porque era isso que eu estava procurando e achei que alguém mais poderia usá-la).

Eu humildemente submeto:

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
    }
}
Matt
fonte
1
Swift String tem um método chamado capitalizedString. Se você precisa aplicá-la a uma matriz de strings verificar esta resposta 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
fonte
0

Aqui está o que eu fiz em pequenos passos, é semelhante ao @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
fonte
0
func helperCapitalizeFirstLetter(stringToBeCapd:String)->String{
    let capString = stringToBeCapd.substringFromIndex(stringToBeCapd.startIndex).capitalizedString
    return capString
}

Também funciona, basta passar sua string e obter uma maiúscula de volta.

Dan Leonard
fonte
0

Atualização Swift 3

A replaceRangefunção é agorareplaceSubrange

nameOfString.replaceSubrange(nameOfString.startIndex...nameOfString.startIndex, with: String(nameOfString[nameOfString.startIndex]).capitalized)
Brendt Bly
fonte
o método capitalizedString foi renomeado para capitalizado
Rool Paap
0

Sou parcial com esta versão, que é uma versão limpa de outra resposta:

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

Ele se esforça para ser mais eficiente avaliando apenas os caracteres self.uma vez e, em seguida, usa formas consistentes para criar as sub-strings.

Patrick Beard
fonte
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
fonte
String já tem uma propriedade chamada capitalizedexatamente para esse fim
Leo Dabus
0

Se você deseja colocar em maiúscula cada palavra da string, pode usar esta extensão

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

Usava

print("simple text example".wordUppercased) //output:: "Simple Text Example"
Shilpriya
fonte
2
Basta usar.capitalized
kakubei
0

Se sua string estiver em maiúsculas, o método abaixo funcionará

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

Esta extensão irá ajudá-lo

extension StringProtocol {
    var firstUppercased: String {
        guard let first = first else { return "" }
        return String(first).uppercased() + dropFirst()
    }
}
Ashu
fonte
1
Basta usar.capitalized
kakubei
@kakubei Por que você faz voto negativo. Este método é para o caso Sentance. Em maiúsculas fará todo primeiro caractere da palavra em maiúsculas. Cadeia de exemplo: - (ISTO É UM MENINO) .capitalizedretornará (Este é um garoto) e este método retornará (Este é um garoto) Ambos são diferentes. (Por favor, + ve Voto ou remover negativo)
Ashu
Você está certo @ashu, minhas desculpas. No entanto, não posso votar até você editar a resposta, então talvez faça apenas uma pequena edição de espaço em branco e eu a votarei. Desculpe de novo.
Kakubei
Não há necessidade de inicializar uma String com o primeiro caractere. return first.uppercased() + dropFirst()ou retorno de um forro(first?.uppercased() ?? "") + dropFirst()
Leo Dabus
0

Adicione esta linha no método viewDidLoad ().

 txtFieldName.autocapitalizationType = UITextAutocapitalizationType.words
Pranit
fonte
-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
fonte
-1

Para o swift 5, você pode fazer o seguinte:

yourString.firstUppercased

Amostra: "abc" -> "Abc"

Hula
fonte
Não há nenhuma propriedade firstcascase em Swift
Leo Dabus