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.
kakubei

2
@Kirsteins: ти маєш рацію, моя погана. Я забув імпортувати Foundation
вівчарську

3
@LoryLory Використовуйте .uppercaseStringдля цього
Кірштейн

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

Швидкий 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
Хороша робота. Я відредагував шахту, щоб спершу пропустити малі літери і перейменований на "Правильний"
ericgu

Мені подобається швидке рішення 2.1.1, але коли я запускаю свою програму і перевіряю на наявність витоків, це показує, що це протікає.
Генні Лі

1
Я щойно створив новий проект, і, здається, це спричиняє витік пам'яті, коли це використовується разом із UITextFieldспостерігачем UITextFieldTextDidChangeNotification.
Генні Лі

@ Генрі це не має нічого спільного з самим кодом. якщо у вас виникли проблеми з продуктивністю / пам'яттю, ви можете повідомити про це Apple.
Лев Дабус

1
@LeoDabus Я думаю, що це залежить від того, який з них робить наміри коду більш очевидними. Пустий рядок буквально, мабуть, найкращий.
Nicolas Miari

84

Swift 3.0

для "Hello World"

nameOfString.capitalized

або для "HELLO WORLD"

nameOfString.uppercased

3
Карлізм уже відповів версією Swift 3 два місяці тому ...
Ерік Айя

11
Це дозволить використовувати великі літери кожного слова рядка, а не лише першого слова.
Bocaxica

Повертає: велику копію рядка. громадський функ верхнього регістру () -> Рядок Swift 3.0 або для "привіту світу" nameOfString.uppercased ЗАМІСТЬ НАД nameOfString.uppercased ()
Azharhussain Шейх

40

Swift 4.0

string.capitalized(with: nil)

або

string.capitalized

Однак це пише великі літери кожного слова

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

Прописана величина - це рядок з першим символом у кожному слові, зміненому на відповідне велике значення, а всі інші символи встановлені на відповідні малі величини. "Слово" - це будь-яка послідовність символів, обмежена пробілами, вкладками або термінаторами рядків. Деякі поширені розділові знаки, що розмежовують слова, не враховуються, тому ця властивість може не давати бажаних результатів для рядків з декількома словами. Додаткову інформацію див. У методі getLineStart (_: end: contentEnd: for :).


1
Я поняття не маю, чому люди не сприйнятливі до цієї відповіді. Якщо люди хочуть лише перше слово з великої літери, вони можуть витягнути перше і використовувати його з великої літери найпростіше.
ScottyBlades

1
Важливо, що "Великі літери" є правильними для всіх символів Unicode, тоді як використання "верхнього регістру" для першого символу не є.
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())
    }
}

Це найкраща відповідь ІМО - це просто для всіх майбутніх випадків.
Роберт

Не потрібно перевіряти, чи є рядок 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
Оголошено. Однак це передбачає, що початковий рядок - це малі регістри. Я додав .localizedLowercaseStringнаприкінці, щоб він працював із рядками типу: aNYsTring. String(nameOfString.characters.prefix(1)).uppercaseString + String(nameOfString.characters.dropFirst()).localizedLowercaseString
oyalhi

4

Swift 3 (xcode 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



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 {нехай діапазон = s.startIndex ... s.startIndex нехай оригінал = s.substringWithRange (діапазон) нехай з великої літери = original.capitalizedString, якщо оригінал == з великої літери {return s} s.replaceRange (діапазон, з: з великої літери)} return s}
David H

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
Лео Dabus

1

Швидкий 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

Швидке оновлення 3

Функція replaceRangeзараз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: " ")
    }
}

У String вже є властивість, названа capitalizedсаме для цієї мети
Лев Дабус

0

Якщо ви хочете писати великими літерами кожне слово рядка, ви можете використовувати це розширення

Швидкий 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повернеться (Це хлопчик), і цей метод повернеться (Це хлопчик) Обидва різні. (Будь ласка, зробіть + проголосуйте або видаліть мінус)
Ашу

Ти маєш рацію @ashu, мої вибачення. Однак я не можу подати заявку, поки ви не відредагуєте відповідь, тому, можливо, просто зробіть невеликий пробіл у редагуванні, і я виправдаю його. Знову вибачте.
kakubei

Не потрібно ініціалізувати рядок з першим символом. 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.