如何从 Swift 中的字符串中返回第一个单词?

Posted

技术标签:

【中文标题】如何从 Swift 中的字符串中返回第一个单词?【英文标题】:How to return a first word from a string in Swift? 【发布时间】:2016-09-23 18:24:58 【问题描述】:

例如,如果我们有这样的情况:

 var myString = "Today was a good day"

返回第一个单词“Today”的最佳方式是什么?我认为应该应用映射,但不确定如何应用。

谢谢。

【问题讨论】:

【参考方案1】:

我能想到的最简单的方法是

斯威夫特 3

let string = "hello world"
let firstWord = string.components(separatedBy: " ").first

斯威夫特 2.2

let string = "hello world"
let firstWord = string.componentsSeparatedByString(" ").first

如果您认为需要在代码中大量使用它,请将其设为 extension

extension String 
    func firstWord() -> String? 
        return self.components(separatedBy: " ").first
    

用法

let string = "hello world"
let firstWord = string.firstWord()

【讨论】:

取决于字符串,这可能太天真了。例如,“你好,世界!”会产生“你好”,这可能是也可能不是你想要的。也许试试let separators = " ,.;:*?" /* word boundaries */ let components = self.components(separatedBy: CharacterSet.init(charactersIn: separators) ) let firstWord = components.first【参考方案2】:

您可以使用 StringProtocol 方法 enumerateSubstrings(in: Range<String.Index>) 和选项 .byWords 来枚举字符串中的单词并获取第一个元素:

Swift 5.1 • Xcode 11 或更高版本

注意:对于较旧的 Swift 语法,请查看此帖子编辑 history

import Foundation

extension StringProtocol 

    var byLines: [SubSequence]  components(separated: .byLines) 
    var byWords: [SubSequence]  components(separated: .byWords) 

    func components(separated options: String.EnumerationOptions)-> [SubSequence] 
        var components: [SubSequence] = []
        enumerateSubstrings(in: startIndex..., options: options)  _, range, _, _ in components.append(self[range]) 
        return components
    

    var firstWord: SubSequence? 
        var word: SubSequence?
        enumerateSubstrings(in: startIndex..., options: .byWords)  _, range, _, stop in
            word = self[range]
            stop = true
        
        return word
    
    var firstLine: SubSequence? 
        var line: SubSequence?
        enumerateSubstrings(in: startIndex..., options: .byLines)  _, range, _, stop in
            line = self[range]
            stop = true
        
        return line
    


游乐场测试:

let string = "• Today was a good day.\n• Tomorrow will be better.\n"

let firstWord = string.firstWord                               // "Today"
let firstLine = string.firstLine                               // "• Today was a good day."
let firstLineLastWord = string.firstLine?.byWords.last         // day
let firstLineLast2Words = string.firstLine?.byWords.suffix(2)  // ["good", "day"]

【讨论】:

【参考方案3】:

我更喜欢使用CharacterSet,因为单词可以用空格和标点符号分隔。

var myString    = "Today was a good day"
let nonLetters  = CharacterSet.letters.inverted
let first       = myString.components(separatedBy: nonLetters).first

【讨论】:

完美!美丽而优雅的解决方案。谢谢。【参考方案4】:

为了避免为了获取第一个单词而处理整个字符串,您可以这样做:

let string = "Hello World"
let word1  = string.prefix (c:Character) in CharacterSet.letters.contains(c.unicodeScalars.first!) 

【讨论】:

请注意,如果您不想枚举整个字符串,您可以在找到第一个单词后将 enumeratedSubsrstrings 停止在范围内。 为什么不简单地prefix $0 != " " ?如果你特别偏执prefix String($0).rangeOfCharacter(from: .whitespaces) == nil 或使用字母方法prefix String($0).rangeOfCharacter(from: .letters) != nil 请注意,所有这些仅在单词位于字符串开头时才有效。试试"•Sugar" 我想确保检测到任何非字母分隔符(不仅仅是空格)。此外,对我来说,将每个字母转换为字符串进行处理似乎并不那么简单(或高效)。 只使用第一个 Unicode 值似乎也不正确 它不适用于表情符号等复合 unicode 字符,但适用于所有罗马字符集。【参考方案5】:

尝试使用prefix()函数

let string = "Today was a good day"
if let spaceIndex = string.firstIndex(of: " ") 
    let firstWord = String(string.prefix(upTo: string.index(after: spaceIndex)))
    print(firstWord)      // Today

【讨论】:

以上是关于如何从 Swift 中的字符串中返回第一个单词?的主要内容,如果未能解决你的问题,请参考以下文章

如何从字符串中提取第一个和最后一个单词?

C#如何替换字符串中的第一个单词

我如何获得第一个双引号中的值?

如何强制返回按钮转到第一个视图控制器(swift)

Swift仅将.uppercaseString应用于字符串的第一个字母

如何大写字符串中每个单词的第一个字符