Как найти в тексте строго трехзначное число?
Мне нужно определять из текста строго трехзначное число.
Пробовал:
re.findall('[0-9]{3}', '1234')
Выводит "123", а мне нужно, чтобы ничего не выводило, т.к. число четырехзначное.
Либо, если текст такой "123-123", то нужно, чтобы тоже ничего не выводило.
Какой способ посоветуете?
Ответы (3 шт):
Пример: regex101
(?:(?<=[^\w-])|(?<=^))\d{3}(?:(?=[^\w-])|(?=$))
Устанавливаем границы самостоятельно. Как в комментариях указали - \b указывает на границы слова, здесь определяем границы слова самостоятельно.
(?<=[^\w-])|(?<=^) - позитивный просмотр назад, либо все символы, кроме цифр, букв, нижнего подчеркивания и тире, либо начало строки. Далее захват 3 цифр, после чего аналогично построенный позитивный просмотр вперед. В случае, если нужно будет ограничить символы, после которых не должен быть захват 3х цифр, прописывать как раз в этих группах.
Решением будет такое выражение, которое найдёт 3-значное число между пробельными символами или началом/концом строки (т.е. с использованием пробельных границ):
re.findall(r'(?<!\S)[0-9]{3}(?!\S)', '987 6781 t 444 t 1234 zzz 453')
# => ['987', '444', '453']
Хотя, в таком случае, зачем нужны регулярные выражения?
[x for x in '987 6781 t 444 t 1234 zzz 453'.split() if len(x) == 3 and all(z.isdigit() for z in x)]
# => ['987', '444', '453']
Если границы не пробельные, а....
- дефисно-цифровые:
re.findall(r'(?<![-\d])[0-9]{3}(?![-\d])', '-987 123-123 444- t 1234 zzz 453')=>['453'] - не между цифрами или цифрой+дефисом или дефисом+цифрой:
re.findall(r'(?<!\d)(?<!\d-)[0-9]{3}(?!-?\d)', '-987 123-123 444- t 1234 zzz 453')=>['987', '444', '453']
Дополнительно
Очень часто пользователи, спрашивающие, как проверить строку на строгое соответсвтие шаблону, имеют в виду:
- Полное соответствие строки шаблону:
bool(re.fullmatch(r'[0-9]{3}', '123'))=>True(ещёre.match(r'[0-9]{3}$', '123')иre.search(r'^[0-9]{3}$', '123')) - Не между буквами/цифрами/знаком подчёркивания:
re.findall(r'\b[0-9]{3}\b', '123,456,12345,b123,876_')=>['123', '456'] - Не между буквами/цифрами (исключая знак подчёркивания):
re.findall(r'(?<![^\W_])[0-9]{3}(?![^\W_])', '123,456,12345,b123,876_')=>['123', '456', '876'] - Не в дробных числах:
re.findall(r'(?<!\d)(?<!\d[.,])[0-9]{3}(?![.,]?\d)', '987.564 123-123 444,1234--453.')=>['123', '123', '453'](удалите либо символ точки, либо запятой по вашему усмотрению).