Проверьте, содержит ли строка специальные символы в Swift

Мне нужно определить, содержит ли строка какие-либо специальные символы. Как я могу проверить это? Поддерживает ли Swift регулярные выражения?

var characterSet:NSCharacterSet = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789")
if (searchTerm!.rangeOfCharacterFromSet(characterSet).location == NSNotFound){
    println("Could not handle special characters")
}

Я пробовал код выше, но он соответствует только, если я ввожу первый символ в качестве специального символа.

Ответы

Ответ 1

Ваш код проверяет, нет ли символа в строке из заданного набора. Вы хотите проверить, нет ли какого-либо символа в заданном наборе:

if (searchTerm!.rangeOfCharacterFromSet(characterSet.invertedSet).location != NSNotFound){
    println("Could not handle special characters")
}

Вы также можете добиться этого, используя регулярные выражения:

let regex = NSRegularExpression(pattern: ".*[^A-Za-z0-9].*", options: nil, error: nil)!
if regex.firstMatchInString(searchTerm!, options: nil, range: NSMakeRange(0, searchTerm!.length)) != nil {
    println("could not handle special characters")

}

Образец [^A-Za-z0-9] соответствует символу, который не соответствует диапазонам A-Z, a-z или 0-9.

Обновление для Swift 2:

let searchTerm = "a+b"

let characterset = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
if searchTerm.rangeOfCharacterFromSet(characterset.invertedSet) != nil {
    print("string contains special characters")
}

Обновление для Swift 3:

let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
if searchTerm.rangeOfCharacter(from: characterset.inverted) != nil {
    print("string contains special characters")
}

Ответ 2

Этот ответ может помочь людям, которые используют Swift 4.1

func hasSpecialCharacters() -> Bool {

    do {
        let regex = try NSRegularExpression(pattern: ".*[^A-Za-z0-9].*", options: .caseInsensitive)
        if let _ = regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions.reportCompletion, range: NSMakeRange(0, self.count)) {
            return true
        }

    } catch {
        debugPrint(error.localizedDescription)
        return false
    }

    return false
}

Взял ссылку от @Martin R ответа.

Ответ 3

Инвертирование набора символов будет работать, потому что в вашем наборе символов у вас есть все допустимые символы:

var characterSet:NSCharacterSet = NSCharacterSet(charactersInString: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789")
if (searchTerm!.rangeOfCharacterFromSet(characterSet.invertedSet).location == NSNotFound){
    println("No special characters")
}

Надеюсь, это поможет..:)

Ответ 4

@Martin R отлично, я просто хотел его обновить (вторая часть) до версии Swift 2.1

let regex = try! NSRegularExpression(pattern: ".*[^A-Za-z0-9].*", options: NSRegularExpressionOptions())
if regex.firstMatchInString(searchTerm!, options: NSMatchingOptions(), range:NSMakeRange(0, searchTerm!.characters.count)) != nil {
    print("could not handle special characters")
}

Я использовал try!, так как мы можем быть уверены, что создаем регулярное выражение, оно не основывается на динамическом виде данных

Ответ 5

Проверка пароля С помощью: - (Пароль длиной не менее восьми символов, один специальный символ, один заглавный, одна строчная буква и одна цифра)

var isValidateSecialPassword : Bool {

        if(self.count>=8 && self.count<=20){
        }else{
            return false
        }
        let nonUpperCase = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZ").inverted
        let letters = self.components(separatedBy: nonUpperCase)
        let strUpper: String = letters.joined()

        let smallLetterRegEx  = ".*[a-z]+.*"
        let samlltest = NSPredicate(format:"SELF MATCHES %@", smallLetterRegEx)
        let smallresult = samlltest.evaluate(with: self)

        let numberRegEx  = ".*[0-9]+.*"
        let numbertest = NSPredicate(format:"SELF MATCHES %@", numberRegEx)
        let numberresult = numbertest.evaluate(with: self)

        let regex = try! NSRegularExpression(pattern: ".*[^A-Za-z0-9].*", options: NSRegularExpression.Options())
        var isSpecial :Bool = false
        if regex.firstMatch(in: self, options: NSRegularExpression.MatchingOptions(), range:NSMakeRange(0, self.count)) != nil {
            print("could not handle special characters")
            isSpecial = true
        }else{
            isSpecial = false
        }
        return (strUpper.count >= 1) && smallresult && numberresult && isSpecial
    }

Ответ 6

В зависимости от определения специальных символов вы можете использовать это:

let chars =  "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLKMNOPQRSTUVWXYZ0123456789"

chars.canBeConvertedToEncoding(NSASCIIStringEncoding)

Ответ 7

Два решения:

1)

extension String {
    var stripped: String {
        let okayChars = Set("abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLKMNOPQRSTUVWXYZ")
        return self.filter {okayChars.contains($0) }
    }
}

2)

class TrimDictionary {

    static func trimmedWord(wordString: String) -> String {
        var selectedString = wordString

        let strFirst = selectedString.first
        let strLast = selectedString.last

        let characterset = CharacterSet(charactersIn: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
        if strFirst?.description.rangeOfCharacter(from: characterset.inverted) != nil {
            selectedString = String(selectedString.dropFirst())
        }
        if strLast?.description.rangeOfCharacter(from: characterset.inverted) != nil {
            selectedString = String(selectedString.dropLast())
        }
        return selectedString
    }
}

Ответ 8

Ответ махендры можно немного сократить, используя инверсию (^) в предложении регулярных выражений. Кроме того, вам не нужны A-Z и a-z при использовании параметра caseInsensitive, поскольку Swift покрывает эту возможность для вас:

extension String {

  func containsSpecialCharacters(string: String) -> Bool {
        
        do {
            let regex = try NSRegularExpression(pattern: "[^a-z0-9 ]", options: .caseInsensitive)
            if let _ = regex.firstMatch(in: string, options: [], range: NSMakeRange(0, string.count)) {
                return true
            } else {
                return false
            }
        } catch {
            debugPrint(error.localizedDescription)
            return true
        }
    }

Ответ 9

В целях санации имени файла я предпочитаю обнаруживать недопустимые символы, а не предоставлять разрешенный набор символов. В конце концов, многим не говорящим по-английски пользователям нужны акцентированные символы. Следующая функция вдохновлена этой сущностью:

func checkForIllegalCharacters(string: String) -> Bool {
    let invalidCharacters = CharacterSet(charactersIn: "\\/:*?\"<>|")
    .union(.newlines)
    .union(.illegalCharacters)
    .union(.controlCharacters)

    if string.rangeOfCharacter(from: invalidCharacters) != nil {
        print ("Illegal characters detected in file name")
        // Raise an alert here
        return true
    } else {
    return false
}