2015-04-16 19 views
9

Mam ciąg złożony ze słów, z których niektóre zawierają znaki interpunkcyjne, które chciałbym usunąć, ale nie byłem w stanie wymyślić, jak to zrobić.Jak mogę usunąć lub zastąpić wszystkie znaki interpunkcyjne z ciągu?

Na przykład, jeśli mam coś

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

Chciałabym móc utworzyć tablicę z

"[Hello, this, is, a, string]" 

mojego oryginalnego myślenia było użyć czegoś jak words.stringByTrimmingCharactersInSet(), aby usunąć wszelkie znaki I nie chciałem, ale to zabrałoby postacie tylko z końców.

pomyślałem, że może mógłbym iterację napisu z czymś w stylu

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

ale jestem pewien sposób, aby usunąć znak z łańcucha. Jestem pewien, że istnieją pewne problemy ze sposobem, w jaki jest ustawione oświadczenie if, ale pokazuje mój proces myślowy.

Odpowiedz

10

Xcode 8.3.2 • Swift 3,1

extension String { 
    var words: [String] { 
     return components(separatedBy: .punctuationCharacters) 
      .joined() 
      .components(separatedBy: .whitespaces) 
      .filter{!$0.isEmpty} 
    } 
} 

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

Skończyło się na tym, że użyłem mikstury z kilku z tych rozwiązań, aby to zadziałało, ale ten pomógł mi uzyskać ostatni błąd, który naprawiłem. W końcu utworzyłem NSMutableCharacterset, który był alfanumerycznyCharacterSet plus "". Potem skorzystałem z rozwiązania, aby uzyskać to, czego potrzebowałem, bez dodatkowych przestrzeni. – qmlowery

0

NSScaner sposób:

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) 
+0

nie podzielone na znak spacji. – halex

+0

Nie zapewnia to odpowiedzi na pytanie. Aby skrytykować lub poprosić o wyjaśnienie od autora, pozostaw komentarz pod swoim postem. –

+0

@halex Przepraszamy za zły wpis. Zmodyfikowałem mój post. – nickcheng

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

Alternatywny sposób filtrowania znaków z zestawu i uzyskać tablica o f słowa są przy użyciu metod tablicy filter i reduce. Nie jest tak kompaktowy jak inne odpowiedzi, ale pokazuje, jak ten sam wynik można uzyskać w inny sposób.

pierwsze zdefiniować tablicę znaków do usunięcia:

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

obok przekonwertować ciąg wejściowy do tablicy znaków:

let arrayOfChars = Array(words) 

Teraz możemy wykorzystać reduce zbudować ciąg otrzymany przez dołączenie elementów od arrayOfChars, pomijając wszystkie zawarte w charactersToRemove:

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

Powoduje utworzenie ciągu znaków bez znaków interpunkcyjnych (zgodnie z definicją w charactersToRemove).

2 ostatnie kroki:

podzielić ciąg na tablicę słowy, korzystając z pustego znaku jako separatora:

let arrayOfWords = filteredString.componentsSeparatedByString(" ") 

ostatnie, należy usunąć wszystkie puste elementy:

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

String ma metodę enumerateSubstringsInRange(). Z opcją .ByWords, wykrywa granice słów i interpunkcyjnych się automatycznie:

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

Dziękujemy za wyliczenieSubstringsInRange & .ByWords. Bardzo interesujące. –

+0

Ten kod musi zostać zaktualizowany dla wersji 4 lub może być szybki 3 –

+0

@InderKumarRathore: Zaktualizowany dla Swift 3. (Powinien również działać w Swift 4, sprawdzę to później) - Dzięki za powiadomienie! –

2

to działa z Xcode 8.1 , Swift 3:

Najpierw zdefiniuj rozszerzenie ogólnego przeznaczenia do filtrowania przez 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 
    } 
} 

Następnie filtrować za pomocą znaków interpunkcyjnych:

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