Захватить все цифры до трех цифр

У меня есть следующая строка:

1 2 134 2009

И я хотел бы захватить строки с 1-3 цифрами, поэтому результат должен быть:

['1', '2', '134']

То, что я сейчас имею, фиксирует их, но также фиксирует "первые 3" цифры в строках, которые содержат более 3 цифр. Это текущее регулярное выражение у меня есть:

>>> re.findall(r'\d{1,3}', '1 2 134 2009')
['1', '2', '134', '200', '9']

# or a bit closer --

>>> re.findall(r'\d{1,3}(?!\d)', '1 2 134 2009')
['1', '2', '134', '009']

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

Ответы

Ответ 1

Добавьте границы слова:

import re

result = re.findall(r'\b\d{1,3}\b', '1 2 134 2009')

print(result)

Выход

['1', '2', '134']

Из документации \b:

Соответствует пустой строке, но только в начале или конце слова. Слово определяется как последовательность символов слова. Обратите внимание, что формально, \b определяется как граница между символами \w и\W (или наоборот), или между \w и началом/концом строки. Это означает, что r '\ bfoo\b' соответствует 'foo', 'foo.', '(Foo)', 'bar foo baz', но не 'foobar' или 'foo3'.

По умолчанию буквенно-цифровые символы Юникода используются в шаблонах Юникода, но это можно изменить с помощью флага ASCII. Границы слова определяются текущей локалью, если используется флаг LOCALE. Внутри символьного диапазона \b представляет символ возврата, для совместимости со строковыми литералами Pythons.

Ответ 2

Если в вашей строке есть только цифры, разделенные пробелами, использование re является излишним. Вы можете просто split строку и проверить длину подстрок.

>>> numbers = '1 2 134 2009'
>>> [n for n in numbers.split() if len(n) <= 3]
>>> ['1', '2', '134']