Как категоризировать строку по наличию в ней заданой группы посторонних символов?

У меня есть функция, которая принимает строку.

Строка, переданная функции, может:

  1. Полностью состоять из букв (русских или английских);
  2. Полностью состоять из цифр, знаков препинания и прочих символов (№, @, ~, #);
  3. Состоять из букв, цифр, знаков препинания и прочих символов.

Мне необходимо проверять к какому пункту из списка выше можно отнести строку.

Я могу создать список всех символов и организовать проверку так:

def string_filter(string:str) -> None:

    ban_list = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                '+', '=', '*', '/', '%', '|', '@', '^', '>', '<',
                '?', '!', '#', '№', '_', '-', '(', ')', '{', '}',
                '$', '`', '~', '"', ';', ':', '[', ']']

    letters = True

    for i in ban_list:
        if i in string:
            letters = False

    if letters:
        print('В строке только буквы')
    else:
        print('В строке есть другие символы')

string_filter('only letters')
# Результат вызова >>> В строке только буквы

string_filter('123')
# Результат вызова >>> В строке есть другие символы

Но фактически, этот код не работает и не имеет никакого смысла.

Во-первых, список с кучей символов выглядит не очень эстетично.

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

Пожалуйста, подскажите, как организовать проверку строки и определять, к какому пункту из списка выше она относится?

UPD:

Единственный случай, когда может вернуться единица - в строке есть только буквы:

print(str_category('abc'))
# Результат вызова >>> 1

Вернуться двойка может только тогда, когда в строке нет букв абсолютно, но могут быть цифры и прочие символы:

print(str_category('@1$;%3'))
# Результат вызова >>> 2

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

print(str_category('abc@%4e'))
# Результат вызова >>> 3

UPD2:

In [60]: str_category("english words")
Out[60]: 1 # Буквы

In [61]: str_category("english words и русские слова")
Out[61]: 1 # Буквы

In [62]: str_category("english words & русские слова")
Out[62]: 3 # Буквы + какие-то символы

In [63]: str_category("3.1415")
Out[63]: 2 # Какие-то символы

In [64]: str_category("3.1415 - Pi !!!")
Out[64]: 3 # Буквы + какие-то символы

In [65]: str_category("3.1415, -{}[]) !!!")
Out[65]: 2 # Какие-то символы

Ответы (1 шт):

Автор решения: MaxU

Можно воспользоваться регулярными выражениями:

import re

vocab = {
    1: "Буквы",
    2: "Какие-то символы",
    3: "Буквы + какие-то символы"
}

def str_category(str_, vocab=vocab):
    # unicode_letters_pat = r"[^\W\d_]+$"
    if re.match(r"[\sa-zа-яё]+$", str_, flags=re.I):
        # only letters, space or tab
        return vocab.get(1)
    if re.search(r"[a-zа-яё]", str_, flags=re.I):
        # contains at least one letter
        return vocab.get(3)
    # the rest
    return vocab.get(2)

тесты:

In [147]: str_category("english words")
Out[147]: 'Буквы'

In [148]: str_category("english words и русские слова")
Out[148]: 'Буквы'

In [149]: str_category("english words & русские слова")
Out[149]: 'Буквы + какие-то символы'

In [150]: str_category("3.1415")
Out[150]: 'Какие-то символы'

In [151]: str_category("3.1415 - Pi !!!")
Out[151]: 'Буквы + какие-то символы'

In [152]: str_category("3.1415, -{}[]) !!!")
Out[152]: 'Какие-то символы'

In [153]: str_category("english words 123")
Out[153]: 'Буквы + какие-то символы'
→ Ссылка