【问题标题】:How can I remove or replace all punctuation characters from a String?如何删除或替换字符串中的所有标点符号?
【发布时间】:2015-04-16 06:54:48
【问题描述】:

我有一个由单词组成的字符串,其中一些包含标点符号,我想将其删除,但我一直无法弄清楚如何做到这一点。

例如,如果我有类似的东西

var words = "Hello, this : is .. a  string?"

我希望能够用

创建一个数组
"[Hello, this, is, a, string]"

我最初的想法是使用 words.stringByTrimmingCharactersInSet() 之类的东西来删除我不想要的任何字符,但这只会删除字符。

我想也许我可以用类似的东西遍历字符串

for letter in words {
    if NSCharacterSet.punctuationCharacterSet.characterIsMember(letter){
        //remove that character from the string
    }
}

但我不确定如何从字符串中删除字符。我确信 if 语句的设置方式也存在一些问题,但它显示了我的思考过程。

【问题讨论】:

    标签: ios swift macos


    【解决方案1】:

    Xcode 11.4 • Swift 5.2 或更高版本

    extension StringProtocol {
        var words: [SubSequence] {
            split(whereSeparator: \.isLetter.negation)
        }
    }
    

    extension Bool {
        var negation: Bool { !self }
    }
    

    let sentence = "Hello, this : is .. a  string?"
    let words = sentence.words  // ["Hello", "this", "is", "a", "string"]
    
     
    

    【讨论】:

    • 我最终混合使用了其中一些解决方案来使其工作,但这个解决方案帮助我解决了我修复的最后一个错误。我最终创建了一个 NSMutableCharacterset,它是 alphanumericCharacterSet 加上“”。然后我使用这里的解决方案来获得我需要的东西,而无需额外的空格。
    • 很好解释。谢谢!
    【解决方案2】:

    String 有一个enumerateSubstringsInRange() 方法。 使用.ByWords 选项,它可以检测字边界和 自动标点符号:

    斯威夫特 3/4:

    let string = "Hello, this : is .. a \"string\"!"
    var words : [String] = []
    string.enumerateSubstrings(in: string.startIndex..<string.endIndex,
                                      options: .byWords) {
                                        (substring, _, _, _) -> () in
                                        words.append(substring!)
    }
    print(words) // [Hello, this, is, a, string]
    

    斯威夫特 2:

    let string = "Hello, this : is .. a \"string\"!"
    var words : [String] = []
    string.enumerateSubstringsInRange(string.characters.indices,
        options: .ByWords) {
            (substring, _, _, _) -> () in
            words.append(substring!)
    }
    print(words) // [Hello, this, is, a, string]
    

    【讨论】:

    • 感谢 enumerateSubstringsInRange 和 .ByWords。很有趣。
    • 此代码需要为swift 4更新或者可能是swift 3
    • @InderKumarRathore:已针对 Swift 3 进行了更新。(它应该也可以在 Swift 4 中使用,我稍后会检查)– 感谢您的通知!
    • @MartinR 哈哈!我正要通过从您的另一个答案中获取信息来更新您的答案:stackoverflow.com/a/39534217/468724,但您在我之前更新了它。顺便说一句,这适用于 swift 4。感谢伙伴的快速响应:)
    【解决方案3】:

    这适用于 Xcode 8.1、Swift 3:

    首先定义CharacterSet过滤的通用扩展:

    extension String {
      func removingCharacters(inCharacterSet forbiddenCharacters:CharacterSet) -> String 
    {
        var filteredString = self
        while true {
          if let forbiddenCharRange = filteredString.rangeOfCharacter(from: forbiddenCharacters)  {
            filteredString.removeSubrange(forbiddenCharRange)
          }
          else {
            break
          }
        }
    
        return filteredString
      }
    }
    

    然后使用标点符号过滤:

    let s:String = "Hello, world!"
    s.removingCharacters(inCharacterSet: CharacterSet.punctuationCharacters) // => "Hello world"
    

    【讨论】:

      【解决方案4】:

      从集合中过滤字符并获得单词数组的另一种方法是使用数组的filterreduce 方法。它不像其他答案那样紧凑,但它显示了如何以不同的方式获得相同的结果。

      首先定义一个要删除的字符数组:

      let charactersToRemove = Set(Array(".:?,"))
      

      接下来将输入字符串转换为字符数组:

      let arrayOfChars = Array(words)
      

      现在我们可以使用reduce 构建一个字符串,通过附加来自arrayOfChars 的元素获得,但跳过所有包含在charactersToRemove 中的元素:

      let filteredString = arrayOfChars.reduce("") {
          let str = String($1)
          return $0 + (charactersToRemove.contains($1) ? "" : str)
      }
      

      这会产生一个没有标点符号的字符串(如charactersToRemove 中所定义)。

      最后两步:

      将字符串拆分为单词数组,使用空白字符作为分隔符:

      let arrayOfWords = filteredString.componentsSeparatedByString(" ")
      

      最后,删除所有空元素:

      let finalArrayOfWords = arrayOfWords.filter { $0.isEmpty == false }
      

      【讨论】:

        【解决方案5】:

        NSScaner 方式:

        let words = "Hello, this : is .. a  string?"
        
        //
        let scanner = NSScanner(string: words)
        var wordArray:[String] = []
        var word:NSString? = ""
        
        while(!scanner.atEnd) {
          var sr = scanner.scanCharactersFromSet(NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKMNOPQRSTUVWXYZ"), intoString: &word)
          if !sr {
            scanner.scanLocation++
            continue
          }
          wordArray.append(String(word!))
        }
        
        println(wordArray)
        

        【讨论】:

        • 这不会在空格字符上分割。
        • 这并没有提供问题的答案。要批评或要求作者澄清,请在其帖子下方发表评论。
        • @halex 抱歉发错了。我已经修改了我的帖子。
        • @MD 感谢您的留言:)
        【解决方案6】:
        let charactersToRemove = NSCharacterSet.punctuationCharacterSet().invertedSet
        let aWord = "".join(words.componentsSeparatedByCharactersInSet(charactersToRemove))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-26
          • 2020-01-09
          • 2017-05-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多