Подтвердить что ты не робот

Какое правильное регулярное выражение подходит для сопоставления значений, генерируемых uuid.uuid4(). Hex?

Как проверить, что значение равно UUID4, сгенерированному этим кодом?

uuid.uuid4().hex

Должно ли быть какое-то регулярное выражение? Значения, сгенерированные строками длиной 32 символа этой формы:

60e3bcbff6c1464b8aed5be0fce86052
4b9b3361

Ответ 1

достаточно просто:

import re
uuid4hex = re.compile('[0-9a-f]{32}\Z', re.I)

Это соответствует только строкам, которые представляют собой ровно 32 шестнадцатеричных символа, если вы используете метод .match() (поиск начинается с начала строки, см. .search() против .match()). \Z соответствует концу строки (vs. $, которая будет соответствовать в конце строки или новой строки).

Ответ 2

Насколько я знаю, ответ Martijn не соответствует 100%. UUID-4 имеет пять групп шестнадцатеричных символов, первый имеет 8 символов, второй 4 символа, третий 4 символа, четвертый 4 символа, пятый 12 символов.

Однако, чтобы сделать его допустимым UUID4, третья группа (первая в средняя) должна начинаться с 4:

00000000-0000-4000-0000-000000000000
              ^

И четвертая группа должна начинаться с 8, 9, a или b.

00000000-0000-4000-a000-000000000000
              ^    ^

Итак, вам нужно изменить регулярное выражение Martijn на:

import re
uuid4hex = re.compile('[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z', re.I)

Надеюсь, это поможет!

Ответ 3

Чтобы быть более конкретным. Это самое точное регулярное выражение для ловли uuid4 как с типом, так и без него, и это следует за всеми правилами UUID4:

[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}

Вы можете убедиться, что он также набирает заглавные буквы с флагом игнорирования. В моем примере с re.I. (uuid не имеет заглавных букв в нем, но во входных данных он не прерывается, просто игнорирует его. Значение UUID "f" и "F" одинаково)

Я создал валидатор, чтобы поймать их так:

def valid_uuid(uuid):
    regex = re.compile('^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
    match = regex.match(uuid)
    return bool(match)

Затем вы можете сделать:

if valid_uuid(my_uuid):
    #Do stuff with valid my_uuid

С помощью ^ в начале и \Z в конце я также удостоверяюсь, что в строке ничего нет. Это гарантирует, что "3fc3d0e9-1efb-4eef-ace6-d9d59b62fec5" возвращает true, но "3fc3d0e9-1efb-4eef-ace6-d9d59b62fec5 + 19187" возвращает false.

Обновление - ниже приведенный ниже метод python не является надежным - см. комментарии:

Существуют другие способы проверки UUID. В python выполните:

from uuid import UUID
try:
    UUID(my_uuid)
    #my_uuid is valid and you can use it
except ValueError:
    #do what you need when my_uuid is not a uuid

Ответ 4

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

import re
from uuid import UUID


def _validate_uuid4(uuid_string):
    try:
        UUID(uuid_string, version=4)
    except ValueError:
        return False
    return True

def _validate_uuid4_re(uuid_string):
    uuid4hex = re.compile('^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
    match = uuid4hex.match(uuid_string)
    return bool(match)

В команде ipython:

В [58]: val = str (uuid.uuid4())

In [59]:% time _validate_uuid4 (val) Время ЦП: пользователь 0 нс, sys: 0 нс, всего: 0 нс Время стены: 30,3 мкс Out [59]: верно

In [60]:% time _validate_uuid4_re (val) Время ЦП: пользователь 0 нс, sys: 0 нс, всего: 0 нс Время стены: 25,3 мкс Выход [60]: верно

В [61]: val = "invalid_uuid"

В [62]:% time _validate_uuid4 (val) Время ЦП: пользователь 0 нс, sys: 0 нс, всего: 0 нс Время стены: 29,3 мкс Выход [62]: Ложь

В [63]:% time _validate_uuid4_re (val) Время ЦП: пользователь 0 нс, sys: 0 нс, всего: 0 нс Время стены: 25,5 мкс Выход [63]: Ложь