Swift применяет .uppercaseString только к первой букве строки


232

Я пытаюсь создать систему автозамены, и когда пользователь вводит слово с большой буквы, автозамена не работает. Чтобы это исправить, я сделал копию напечатанной строки, применил .lowercaseString, а затем сравнил их. Если строка действительно опечатка, это должно исправить слово. Однако тогда слово, которое заменяет набранное слово, все в нижнем регистре. Поэтому мне нужно применять .uppercaseString только к первой букве. Я изначально думал, что смогу использовать

nameOfString[0]

но это, видимо, не работает. Как я могу получить первую букву строки в верхнем регистре, а затем иметь возможность напечатать всю строку с первой заглавной буквой?

Спасибо за любую помощь!

Ответы:


512

Включая изменяющиеся и не изменяющиеся версии, которые соответствуют рекомендациям API.

Свифт 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()
    }
}

Свифт 4:

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

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

3
Только примечание, которое .capitalizedStringбольше не работает в Xcode 7 Beta 4. Строки немного изменились в Swift 2.0.
Какубей

2
@Kirsteins: ты прав, мой плохой. Я забыл , чтобы импортировать Foundation робкий оскал
kakubei

3
@LoryLory Используйте .uppercaseStringдля этого
Kirsteins

2
Это очень эффективный ответ, приятель .. Работа с Xcode 7.1.1 / Swift 2.1 .... Спасибо :)
onCompletion

20
его только в .capitalizedнастоящее время. Обратите внимание такжеcapitalizedStringWith(_ locale:)
Рафаэль

152

Swift 5.1 или позже

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
Хорошая работа. Я отредактировал мой, чтобы сначала пропустить строчные буквы, и переименовал в Proper.
ericgu

Мне нравится решение swift 2.1.1, но когда я запускаю свое приложение и проверяю его на наличие утечек, оно показывает, что это утечка.
Хенни Ли

1
Я только что создал новый проект, и кажется, что он вызывает утечку памяти, когда он используется вместе с UITextFieldнаблюдателем для UITextFieldTextDidChangeNotification.
Хенни Ли

@ Генри, это не имеет никакого отношения к самому коду. если у вас возникли проблемы с производительностью / памятью, сообщите об этом в Apple.
Лео Дабус

1
@ LeoDabus Я думаю, это зависит от того, какой из них делает код более очевидным. Пустой строковый литерал, возможно, лучший.
Николас Миари,

84

Swift 3.0

для "Hello World"

nameOfString.capitalized

или для "HELLO WORLD"

nameOfString.uppercased

3
Шарлизм уже ответил с версией Swift 3 два месяца назад ...
Эрик Айя

11
Это будет использовать первый символ каждого слова строки, а не только первое слово.
Bocaxica

Возвращает: прописная копия строки. public func uppercased () -> String Swift 3.0 или для "HELLO WORLD" nameOfString.uppercased ВМЕСТО ВЫШЕ nameOfString.uppercased ()
Ажархусейн Шейх

40

Swift 4.0

string.capitalized(with: nil)

или

string.capitalized

Однако это заглавная буква каждого слова

Документация Apple:

Строка с заглавной буквы - это строка, в которой первый символ в каждом слове заменен на соответствующее значение в верхнем регистре, а все остальные символы установлены на соответствующие им значения в нижнем регистре. «Слово» - это любая последовательность символов, разделенная пробелами, символами табуляции или ограничителями строки. Некоторая распространенная пунктуация с разделением слов не учитывается, поэтому это свойство может обычно не давать желаемых результатов для строк из нескольких слов. См. Метод getLineStart (_: end: contentsEnd: for :) для получения дополнительной информации.


1
Я понятия не имею, почему люди не воспринимают этот ответ. Если люди хотят, чтобы только первое слово было написано с заглавной буквы, они могли бы выхватить первое и легко использовать его с заглавной буквы.
ScottyBlades

1
Важно отметить, что «С заглавной буквы» правильно для всех символов Юникода, в то время как использование «заглавных букв» для первого символа - нет.
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()

Для 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())
    }
}

Это лучший ответ IMO - он прост для всех будущих случаев.
Роберт

Не нужно проверять, если строка isEmptyи инициализировать строку, чтобы заменить либо. Вы можете просто развернуть первый символ, а в случае неудачи просто вернуть ноль. Это можно упростить какvar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Лео Дабус

17

Для использования первого символа в слове .capitalizedв быстром и для целого слова.uppercased()


10

Swift 2.0 (одна строка):

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

1
Upvoted. Тем не менее, это предполагает, что исходная строка все строчные. В .localizedLowercaseStringконце я добавил, чтобы он работал со строками вроде: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi

4

Swift 3 (код 8.3.3)

Прописные буквы всех первых символов строки

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

//Your String

Прописные буквы всех символов

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

//YOUR STRING

Прописные только первый символ строки

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

//Your string

Это не будет использовать только первый символ строки
Rool Paap


3

Я получаю первого персонажа, дублированного решением Кирстейна. Это будет использовать первый символ, не видя двойного:

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

Я не знаю, является ли это более или менее эффективным, я просто знаю, что это дает мне желаемый результат.


Вы можете проверить, меняет ли этот символ заглавные буквы, сохранив его в своей собственной константе, а затем протестировав равенство с новой «заглавной» строкой, и, если они совпадают, у вас уже есть то, что вы хотите.
Дэвид Х

Ваш пост вдохновил на этот ответ - спасибо !: 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, если original == capitalized {return s} s.replaceRange (диапазон, с: прописными буквами)} return s}
Дэвид Х

1
В более новых версиях Swift, countElementsэто просто count.
Джордж Пулос

3

С Swift 3 вы можете легко использовать textField.autocapitalizationType = UITextAutocapitalizationType.sentences


3

Вот версия для Swift 5, которая использует API скалярных свойств Unicode для спасения, если первая буква уже в верхнем регистре или не имеет понятия регистра:

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

Нет необходимости инициализировать строку с первым символом. return first.uppercased() + dropFirst()или один лайнер(first?.uppercased() ?? "") + dropFirst()
Лео Дабус

2

Прописать первый символ в строке

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

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

2

В Swift 3.0 (это немного быстрее и безопаснее, чем принятый ответ):

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

nameOfString.capitalized не будет работать , оно будет использовать заглавные буквы в предложении


1

Кредиты Леонардо Савио Дабуса:

Я полагаю, что большинство случаев использования заключается в получении надлежащего корпуса:

import Foundation

extension String {

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

1

Мое решение:

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
}

Это не чисто быстро.
Абхишек Беди

1

Включая приведенные выше ответы, я написал небольшое расширение, в котором первая буква каждого слова пишется с заглавной буквы (потому что это то, что я искал, и подумал, что кто-то другой может его использовать).

Я смиренно представляю:

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 имеет метод с именем capitalizedString. Если вам нужно применить его к массиву строк, проверьте этот ответ stackoverflow.com/a/28690655/2303865
Лев Дабус

1

Swift 4

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

0

Вот как я это делал маленькими шагами, он похож на @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
}

Также работает просто передать вашу строку и получить заглавную обратно.


0

Swift 3 Обновление

replaceRangeFUNC сейчасreplaceSubrange

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

метод capitalizedString был переименован в прописной
Rool Paap

0

Я неравнодушен к этой версии, которая является очищенной версией из другого ответа:

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

Он стремится быть более эффективным, оценивая self.characters только один раз, а затем использует согласованные формы для создания подстрок.


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

У строки уже есть свойство, которое вызывается capitalizedименно для этой цели
Лео Дабус

0

Если вы хотите использовать заглавные буквы в каждом слове строки, вы можете использовать это расширение

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

Используемый

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

2
просто используйте.capitalized
kakubei

0

Если ваша строка написана заглавными буквами, то метод ниже будет работать

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

Это расширение поможет вам

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

1
просто используйте.capitalized
kakubei

@kakubei Почему ты голосуешь против. Этот метод для случая Sentance. Прописная заглавная будет делать каждый первый символ слова к заглавной. Пример строки: - (ЭТО МАЛЬЧИК) .capitalizedвернется (Это мальчик), и этот метод вернется (Это мальчик) Оба они разные. (Пожалуйста, проголосуйте + ve или удалите негатив)
Ашу

Ты прав @ashu, мои извинения. Однако я не смогу проголосовать, пока вы не отредактируете ответ, поэтому, возможно, просто сделайте небольшой пробел, и я добавлю его. Прости еще раз.
Какубей

Нет необходимости инициализировать строку с первым символом. return first.uppercased() + dropFirst()или один возврат лайнера(first?.uppercased() ?? "") + dropFirst()
Лео Дабус

0

Добавьте эту строку в метод 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

Для Swift 5 вы можете просто сделать так:

yourString.firstUppercased

Образец: "abc" -> "Abc"


В Свифте нет первой недвижимости в верхнем корпусе
Лео Дабус
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.