如何从String中删除或替换所有标点符号?

时间:2015-04-16 06:54:49

标签: swift macos swift2

我有一个由单词组成的字符串,其中一些包含标点符号,我想删除它,但我一直无法弄清楚如何执行此操作。

例如,如果我有类似

的内容
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语句的设置方式也存在一些问题,但它显示了我的思考过程。

6 个答案:

答案 0 :(得分:16)

Xcode 10.2•Swift 5或更高版本

extension StringProtocol {
    var words: [SubSequence] {
        return split{ !$0.isLetter }
    }
}

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

答案 1 :(得分:5)

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

Swift 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]

Swift 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]

答案 2 :(得分: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"

答案 3 :(得分:0)

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)

答案 4 :(得分:0)

通过使用数组的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 :(得分:-1)

let charactersToRemove = NSCharacterSet.punctuationCharacterSet().invertedSet
let aWord = "".join(words.componentsSeparatedByCharactersInSet(charactersToRemove))