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

Рейтинг: 0Ответов: 1Опубликовано: 15.03.2023

Написал функцию, которая проверяет содержимое на символы из определенного алфавита:

import re

def verification(text: str = None) -> bool:
    """Проверка на символы из алфавита <A-Za-zА-Яа-яЁё ;>"""
    if text is None:
        return False
    pattern = r'[a-zA-ZА-Яа-яЁё]|[0-9]|[\s;]'
    return len(text) == len(''.join(re.findall(pattern, text)))

Но, у меня большие сомнения на ее оптимальность. Оптимальна ли она или можно было как-то по производительнее реализовать?

Ответы

▲ 3Принят

Я бы сделал как-то так, не вдаваясь в подробности регулярки:

import re
from functools import lru_cache

pattern = re.compile(r'[a-zA-ZА-Яа-яЁё]|[0-9]|[\s;]')

@lru_cache(1000)
def verification(text: str = None) -> bool:
    """Проверка на символы из алфавита <A-Za-zА-Яа-яЁё ;>"""
    if text is None:
        return False
    
    return len(text) == len(pattern.findall(text))
  1. Компилируем заранее регулярку, так работает быстрее
  2. Строку собирать не нужно, просто проверяем длину выхода findall
  3. Кэшируем собственно функцию (размер кэша подобрать по вкусу, зависит от природы данных, нужен ли тут кэш и какой длины)

Как вариант ещё можно вместо регулярки собрать заранее множество всех допустимых символов, а в функции делать множество из входного текста и вычитать из него множество допустимых символов. Проверка пройдена, если в результате вычитания множеств получается пустое множество. По идее, это должно работать быстрее, чем регулярка, но нужно проверять.