Как проверить, состоит ли строка только из букв и пробелов в Swift 5? - PullRequest
0 голосов
/ 12 марта 2020

Я сейчас пытаюсь проверить поле ввода имени. Для этого я хотел бы проверить ввод.

Ввод является строкой и должен состоять только из букв и пробелов. Есть ли какой-нибудь простой способ реализовать это.

Например, у меня есть Ввод "Jon Doe", как я могу убедиться, что это допустимое имя, в то время как Peter2 или Ben&Jerry нет?

Заранее спасибо за помощь. <3 </p>

Ответы [ 4 ]

7 голосов
/ 12 марта 2020
let lettersAndSpacesCharacterSet = CharacterSet.letters.union(.whitespaces).inverted

let testValid1 = "Jon Doe".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // true
let testInvalid1 = "Ben&Jerry".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // false
let testInvalid2 = "Peter2".rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil // false
2 голосов
/ 12 марта 2020

вы также можете сделать что-то вроде этого

func onlyLettersChecker(string: String) -> Bool {

    let justLettersRegex = "[^A-Za-zÀ-ÖØ-öø-ÿ]"

    let trimmedString = string.replacingOccurrences(of: " ", with: "")
    return trimmedString.isEmpty == false && trimmedString.range(of: justLettersRegex, options: .regularExpression) == nil
}

Вы удаляете пробелы в вашей строке, а затем проверяете, есть ли там только буквы.

Это регулярное выражение принимает ударения в именах вам может понадобиться изменить регулярное выражение, если вам нужны апострофы в именах и так далее.

0 голосов
/ 12 марта 2020

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

  • двуствольные имена («Даниэль Дей-Льюис»);
  • акценты («Жозе Моуринью»);
  • апострофы («Крис О'Дауд»);
  • аббревиатуры для происхождения («Мартин Лютер Кинг-младший»), титулов («Доктор Ли Вэньлян») и верительных грамот («Джон На sh, тел. D. ”)

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

  • незападные наборы символов (« 黒 澤明 »)

Regex изящно справляется с этим, например, для любой буквы и нескольких знаков препинания:

let searchString = #"^([\p{L},.'’-]+(\s|$))+"#

if string.range(of: searchString, options: .regularExpression) != nil {
    print(string, "passed")
} else {
    print(string, "failed")
}

Если вы не хотите разрешать точки или запятые, не стесняйтесь удалить их из приведенного выше регулярного выражения.

0 голосов
/ 12 марта 2020

В зависимости от точных требований, RegEx может быть лучшим маршрутом.

  • Допустимы ли начальные / конечные / дополнительные пробелы?
  • Допустимы ли расширенные латинские символы?
  • Допустимы ли акцентированные имена (дефисы или апострофы)?

Например, с этим списком «именных» записей:

    "Jon Doe",
    "Ben&Jerry",
    "JonDoe",
    "Jon Edward Doe",
    " Jon Doe",
    "Jon   Doe",
    "Jon Doe ",
    "Jon Doe2",
    "José Doe",
    "Jon O'Doe",
    "Jon Doe-Smith",
    "Joß Müller",
    "Jon 黒澤明"

Какие должны быть действительными?

РЕДАКТИРОВАТЬ: обновлен с улучшенным (?) RegEx на основе ответа Роба ...

Используя этот код, который оценивает записи как с .rangeOfCharacter, так и с тестом RegEx :

class ViewController: UIViewController {

    override func viewDidLoad() {

        let names: [String] = [
            "Jon Doe",
            "Ben&Jerry",
            "JonDoe",
            "Jon Edward Doe",
            " Jon Doe",
            "Jon   Doe",
            "Jon Doe ",
            "Jon Doe2",
            "José Doe",
            "Jon O'Doe",
            "Jon Doe-Smith",
            "Joß Müller",
            "Jon 黒澤明",
        ]

        names.forEach {
            test($0)
        }

    }

func test(_ text: String) -> Void {

        let ss = "^[\\p{L}\\p{P}]+\\s[\\p{L}\\p{P}]+$"

        let b1 = text.range(of: ss, options: .regularExpression) != nil

        let lettersAndSpacesCharacterSet = CharacterSet.letters.union(.whitespaces).inverted

        let b2 = text.rangeOfCharacter(from: lettersAndSpacesCharacterSet) == nil

        print("RegEx:", b1, "\t", "Range:", b2, "\t", "[\(text)]")

    }

}

Вывод:

RegEx: true      Range: true     [Jon Doe]
RegEx: false     Range: false    [Ben&Jerry]
RegEx: false     Range: true     [JonDoe]
RegEx: false     Range: true     [Jon Edward Doe]
RegEx: false     Range: true     [ Jon Doe]
RegEx: false     Range: true     [Jon   Doe]
RegEx: false     Range: true     [Jon Doe ]
RegEx: false     Range: false    [Jon Doe2]
RegEx: true      Range: true     [José Doe]
RegEx: true      Range: false    [Jon O'Doe]
RegEx: true      Range: false    [Jon Doe-Smith]
RegEx: true      Range: true     [Joß Müller]
RegEx: true      Range: true     [Jon 黒澤明]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...