【问题标题】:Swap string case - swift交换字符串大小写 - swift
【发布时间】:2015-01-31 19:36:58
【问题描述】:
let str = "tHIS is A test"
let swapped_case = "This IS a TEST"

这里是 Swift 菜鸟,如何以编程方式执行第二条语句?

【问题讨论】:

  • 什么意思?哦,我看到了更改属性!好吧,我猜它是 NSMutableAttributedString 类
  • 对我来说很清楚 :-)

标签: string cocoa swift


【解决方案1】:

此功能适用于所有大写/小写字符 用 Unicode 定义,即使是来自“外来”语言的那些,例如 Ä 或 ć:

func swapCases(_ str : String) -> String {
    var result = ""
    for c in str.characters { // Swift 1: for c in str {
        let s = String(c)
        let lo = s.lowercased() //Swift 1 & 2: s.lowercaseString
        let up = s.uppercased() //Swift 1 & 2: s.uppercaseString
        result += (s == lo) ? up : lo
    }
    return result
}

例子:

let str = "tHIS is a test ÄöÜ ĂćŒ Α" // The last character is a capital Greek Alpha
let swapped_case = swapCases(str)
print(swapped_case)
// This IS A TEST äÖü ăĆœ α

【讨论】:

    【解决方案2】:

    使用 switch 语句范围内检查来确定字母大小写,并使用NSString-bridged 方法进行相应的转换。

    let str = "tHIS is A test"
    let swapped_case = "This IS a TEST"
    
    func swapCase(string: String) -> String {
        var swappedCaseString: String = ""
        for character in string {
            switch character {
            case "a"..."z":
                let uppercaseCharacter = (String(character) as NSString).uppercaseString
                swappedCaseString += uppercaseCharacter
            case "A"..."Z":
                let lowercaseCharacter = (String(character) as NSString).lowercaseString
                swappedCaseString += lowercaseCharacter
            default:
                swappedCaseString += String(character)
            }
        }
    
        return swappedCaseString
    }
    
    swapCase(str)
    

    【讨论】:

      【解决方案3】:

      我有点太晚了,但这也有效:-)

      let str = "tHIS is A test"
      var res = ""
      for c in str {
        if contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ", c) {
          res += "\(c)".lowercaseString
        } else {
          res += "\(c)".uppercaseString
        }
      }
      res
      

      【讨论】:

        【解决方案4】:

        您已经有很多简洁的好答案,但这里有一个过于详尽的有趣答案。

        这确实是map 的工作——遍历集合(在本例中为字符串)并对每个元素(此处为每个字符)执行操作。除了map 接受任何集合,但只返回一个数组,然后您必须再次将其转换为字符串。

        但是这里有一个 map 的版本,给定一个可扩展的集合,它会返回相同类型的可扩展集合。

        (它确实有需要两个集合包含相同类型的限制,但这对于字符串来说很好。你可以让它返回不同的类型,但是你必须告诉它你想要哪种类型,即@987654326 @这会很烦人)

        func map<C: ExtensibleCollectionType>(source: C, transform: (C.Generator.Element) -> C.Generator.Element) -> C {
            var result = C()
        
            for elem in source {
                result.append(transform(elem))
            }
        
            return result
        }
        

        然后要编写转换函数,首先这里是对字符的扩展,类似于其他答案。您必须转换为字符串才能将字符大写,这似乎很不令人满意,真的没有好的(国际字符集友好)方法可以做到这一点吗?

        extension Character {
            var uppercaseCharacter: Character {
                let s = String(self).uppercaseString
                return s[s.startIndex]
            }
        
            var lowercaseCharacter: Character {
                let s = String(self).lowercaseString
                return s[s.startIndex]
            }
        }
        

        还有翻转表壳的功能。我想知道的是这种模式匹配是否对国际友好。似乎是——"A"..."Z" ~= "Ä" 返回 true。

        func flipCase(c: Character) -> Character {
            switch c {
            case "A"..."Z":
                return c.lowercaseCharacter
            case "a"..."z":
                return c.uppercaseCharacter
            default:
                return c
            }
        }
        

        最后:

        let s = map("Hello", flipCase)
        // s is a String = "hELLO"
        

        【讨论】:

        • case "A"..."Z" 匹配“Ä”和“Ć”,但不匹配“Œ”或“Α”(U+0391,希腊大写字母 ALPHA)。并且单个字符的大写字符串实际上可以是多个字符,例如"ß".uppercaseString == "SS"!
        • 啊哈,谢谢,展示了我所知道的!有趣的是它可以将单个字符扩展到多个,也许这是 flatMap 的工作:-) 是否适合采用另一种方式,即如果显示为“SS”,则映射到“ß”?还是从来没有那么明确?
        • "SS" 模棱两可(在德语中)。它可以是“ss”或“ß”的大写。 – 实际上有一个 Unicode 字符“ẞ”U+1E9E 拉丁大写字母 SHARP S,但我从未见过它被使用过。有趣的是,"\u{1E9E}".lowercaseString == "ß" 是真的,但 "ß".uppercaseString == "\u{1E9E}" 是假的。 Unicode Database 没有为 ß (U+00DF) 定义大写字符。 – 简而言之:我不知道确切的转换规则,但似乎转换有时是不可逆的。
        • 顺便说一句,“Ä”匹配“A”...“Z”,因为它可以分解为“A”加上一个组合变音符号。 “Œ”(以及更多国际字母)没有类似的分解。字符串比较是基于规范分解完成的,我在这里做了一些调查:stackoverflow.com/a/25775112/1187415.
        • 感谢您提供的链接答案,它提供了非常丰富的信息,并解释了我想知道的几件事。
        【解决方案5】:

        我希望这会有所帮助。 inputString 和 resultString 分别是输入和输出。

        let inputString = "Example"
        
        let outputString = inputString.characters.map { (character) -> Character in
            let string = String(character)
            let lower = string.lowercased()
            let upper = string.uppercased()
            return (string == lower) ? Character(upper) : Character(lower)
        }
        
        let resultString = String(outputString)
        

        【讨论】:

          【解决方案6】:

          在 Swift 5 中,我通过创建一个遍历字符串的每个字符的函数来实现它,并使用字符串方法更改每个字符,我将每个字符附加回一个新变量:

          func reverseCase(string: String) -> String {
              var newCase = ""
              for char in string {
                  if char.isLowercase {
                      newCase.append(char.uppercased())
                  }
                  else if char.isUppercase {
                      newCase.append(char.lowercased())
                  }
                  else {
                      newCase.append(char)
                  }
              }
              return newCase
          }
          

          然后,当您在打印语句中调用它时,只需将您的字符串传递给函数:

          print(reverseCase(string: str))

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-07-14
            • 1970-01-01
            • 2013-02-01
            • 1970-01-01
            • 2021-08-14
            • 2018-09-07
            • 2016-06-05
            • 2016-01-25
            相关资源
            最近更新 更多