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
Maselko
источник
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())
    }
}
user2260304
источник
Это лучший ответ IMO - он прост для всех будущих случаев.
Роберт
Не нужно проверять, если строка isEmptyи инициализировать строку, чтобы заменить либо. Вы можете просто развернуть первый символ, а в случае неудачи просто вернуть ноль. Это можно упростить какvar firstCharacterUpperCase: String? { guard let first = first else { return nil } return lowercased().replacingCharacters(in: startIndex...startIndex, with: first.uppercased()) }
Лео Дабус
17

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

DURGESH
источник
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

Yura
источник
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())
    }
}
user3699466
источник
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 не будет работать , оно будет использовать заглавные буквы в предложении

pierre23
источник
1

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

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

import Foundation

extension String {

    var toProper:String {
        var result = lowercaseString
        result.replaceRange(startIndex...startIndex, with: String(self[startIndex]).capitalizedString)
        return result
    }
}
ericgu
источник
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
    }
}
Matt
источник
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()
    }
Gayratjon
источник
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)
}
guptron
источник
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"
Shilpriya
источник
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
Pranit
источник
-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
источник
-1

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

yourString.firstUppercased

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

Хула
источник
В Свифте нет первой недвижимости в верхнем корпусе
Лео Дабус