2015-04-08 25 views
16

Próbuję sprawdzić, czy określony ciąg zawiera litery, czy nie.Jak mogę sprawdzić, czy ciąg zawiera litery w Swift?

Do tej pory natknąłem się na NSCharacterSet.letterCharacterSet() jako zestaw liter, ale mam problem z sprawdzeniem, czy znak w tym zestawie znajduje się w danym ciągu znaków. Kiedy używam tego kodu, otrzymuję komunikat o błędzie informujący:

'Charakter' nie jest zamienny do 'unichar'

Dla następującego kodu:

for chr in input{ 
    if letterSet.characterIsMember(chr){ 
     return "Woah, chill out!" 
    } 
} 
+0

Porównaj [Jaki jest najlepszy sposób ustalenia, czy ciąg zawiera znak z zestawu w Swift] (http://stackoverflow.com/questions/28486138/what-is-the-best-way-to-etetine -if-a-string-zawiera-znak-z-zestawu-w)? –

+0

@MartinR Dlaczego "porównywać"? Wygląda mi na całkiem niezły duplikat. – dasblinkenlight

Odpowiedz

32

można użyć NSCharacterSet w następujący sposób:

let letters = NSCharacterSet.letterCharacterSet() 

let phrase = "Test case" 
let range = phrase.rangeOfCharacterFromSet(letters) 

// range will be nil if no letters is found 
if let test = range { 
    println("letters found") 
} 
else { 
    println("letters not found") 
} 

Albo można to zrobić też:

func containsOnlyLetters(input: String) -> Bool { 
    for chr in input { 
     if (!(chr >= "a" && chr <= "z") && !(chr >= "A" && chr <= "Z")) { 
     return false 
     } 
    } 
    return true 
} 

W Swift 2:

func containsOnlyLetters(input: String) -> Bool { 
    for chr in input.characters { 
     if (!(chr >= "a" && chr <= "z") && !(chr >= "A" && chr <= "Z")) { 
     return false 
     } 
    } 
    return true 
} 

To do ciebie, wybrać drogę. Mam nadzieję, że ci to pomoże.

+0

Twój drugi blok kodu nie kompiluje się w Swift, musisz użyć podwójnych cudzysłowów. –

+0

@MartinR Tak, masz rację, dzięki. –

+0

Wypróbowałem pierwsze rozwiązanie i zadziałało, chociaż nie jestem pewien, czy rozumiem linię "if let test = range". – qmlowery

4

Kłopot z .characterIsMember jest to, że zajmuje unichar (typ dla UInt16).

Jeśli iteracyjne swój wkład w widoku napisu utf16, to będzie działać:

let set = NSCharacterSet.letterCharacterSet() 
for chr in input.utf16 { 
    if set.characterIsMember(chr) { 
     println("\(chr) is a letter") 
    } 
} 

Można również pominąć pętlę i użyć algorytmu contains jeśli chcesz tylko sprawdzić obecność/nie- obecność:

if contains(input.utf16, { set.characterIsMember($0) }) { 
    println("contains letters") 
} 
+0

NSCharacterSet ma również metodę longCharacterIsMember, która może być używana z "pełnymi" wartościami Unicode, patrz na przykład http://stackoverflow.com/a/24502779/1187415. –

+0

Ah dzięki, to lepiej, ale wciąż są przypadki skrajne ("!͖̬̰̙̗̿̋ͥͥͣ̐͜͞ "zostanie oznaczony jako litery) –

+0

Co ciekawe, nie przez wyrażenie z' [: alfa:] 'choć –

6

Należy używać wbudowanych funkcji zakresu z NSCharacterSet, zamiast tworzyć własne rozwiązanie. Zapewni to również o wiele większą elastyczność (np. Wyszukiwanie według wielkości liter, jeśli sobie tego życzą).

let str = "Hey this is a string" 
let characterSet = NSCharacterSet(charactersInString: "aeiou") 

if let _ = str.rangeOfCharacterFromSet(characterSet, options: .CaseInsensitiveSearch) { 
    println("true") 
} 
else { 
    println("false") 
} 

Zastępca "aeiou" z dowolnych liter, których szukasz.

Mniej elastyczna, ale jednocześnie przyjemna w obsłudze, jest możliwość korzystania z dowolnej z funkcji dostępnych dla Sequence s. Możesz to zrobić:

contains("abc", "c") 

To oczywiście działa tylko dla pojedynczych znaków, nie jest elastyczne i niezalecane.

Powiązane problemy