Для решения регулярных выражений здесь есть два пути:
- Найдите один недопустимый символ в любом месте строки.
- Проверка каждого символа в строке.
Вот скрипт, который реализует оба:
import re
topic_message = 'This topic is a-ok'
# Option 1: Invalidate one char in string.
re1 = re.compile(r"[<>/{}[\]~`]");
if re1.search(topic_message):
print ("RE1: Invalid char detected.")
else:
print ("RE1: No invalid char detected.")
# Option 2: Validate all chars in string.
re2 = re.compile(r"^[^<>/{}[\]~`]*$");
if re2.match(topic_message):
print ("RE2: All chars are valid.")
else:
print ("RE2: Not all chars are valid.")
Выберите.
Примечание: исходное регулярное выражение ошибочно имеет правую квадратную скобку в классе символов, которую необходимо экранировать.
Тесты: После того, как я увидел интересное решение gnibbler с использованием set()
, мне было интересно узнать, какой из этих методов будет наиболее быстрым, поэтому я решил измерить их. Вот измеренные контрольные данные и утверждения и значения результата timeit
:
Данные испытаний:
r"""
TEST topic_message STRINGS:
ok: 'This topic is A-ok. This topic is A-ok.'
bad: 'This topic is <not>-ok. This topic is {not}-ok.'
MEASURED PYTHON STATEMENTS:
Method 1: 're1.search(topic_message)'
Method 2: 're2.match(topic_message)'
Method 3: 'set(invalid_chars).intersection(topic_message)'
"""
Результаты:
r"""
Seconds to perform 1000000 Ok-match/Bad-no-match loops:
Method Ok-time Bad-time
1 1.054 1.190
2 1.830 1.636
3 4.364 4.577
"""
Тесты производительности показывают, что вариант 1 немного быстрее, чем вариант 2, и оба намного быстрее, чем метод set().intersection()
. Это верно для строк, которые совпадают и не совпадают.