Что такое Regex для UUID
Полезных шаблонов UUID два, и неверный выбор — обычная причина того, что валидатор пропускает мусор. Мягкий шаблон требует лишь 32 hex-символа в раскладке 8-4-4-4-12 и принимает нибл версии, которого нет ни в одном RFC. Строгий дополнительно ограничивает версию диапазоном 1-8, а нибл варианта — набором [89ab], как и требует RFC 9562.
Оба варианта нуждаются в якорях (^ и $) и флаге игнорирования регистра: иначе корректный UUID внутри длинной строки совпадёт, а обрезанное значение посреди предложения покажется допустимым. Скопируйте шаблон для своего языка ниже или вставьте значение в поле проверки.
Как использовать
- Выберите язык и скопируйте шаблон — все они заякорены и нечувствительны к регистру.
- Или вставьте значения в поле слева: каждая строка проверяется строгим шаблоном.
- Смотрите таблицу с версией: она подскажет, случайное это значение (v4) или основанное на времени (v7).
Сценарии
- Валидация ввода в форме или обработчике API, чтобы отсеять некорректный идентификатор до базы.
- Разбор логов и CSV: извлечение идентификаторов из текста без ложных совпадений с 32-символьными хэшами.
- Ограничения в базе, когда столбец остаётся текстовым, но не должен содержать ничего, кроме UUID.
Сравнение Regex для UUID с другими форматами
| Вариант | Когда использовать |
|---|---|
Строгий шаблон | Отклоняет всё, где версия или вариант не соответствуют RFC. Используйте для валидации. |
Мягкий шаблон | Проверяет только раскладку 32 hex-символов. Быстрее, но принимает невозможные версии. |
Проверка существования | Ни одно регулярное выражение не скажет, был ли идентификатор выдан: нужен запрос к данным. |
Примеры кода
JavaScript
// Строгий, с якорями, без учёта регистра
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
// Мягкий: только раскладка
const LOOSE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
// Найти все UUID внутри длинной строки
'ids ' + '550e8400-e29b-41d4-a716-446655440000'.repeat(2)
.match(/[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi);
Python
import re
STRICT = re.compile(r'^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$', re.I)
LOOSE = re.compile(r'^[0-9a-f]{8}(-?[0-9a-f]{4}){3}-?[0-9a-f]{12}$', re.I)
bool(STRICT.match('550e8400-e29b-41d4-a716-446655440000')) # True
bool(STRICT.match('550e8400-e29b-01d4-a716-446655440000')) # False
Java
import java.util.regex.Pattern;
Pattern STRICT = Pattern.compile(
"^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-" +
"[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$");
STRICT.matcher(value).matches(); // true / false
PHP
<?php
$strict = '/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i';
if (preg_match($strict, $value) === 1) {
// корректный UUID
}
Go
package main
import "regexp"
var strict = regexp.MustCompile(`(?i)^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$`)
strict.MatchString(value)
MySQL
-- MySQL 8 поддерживает REGEXP в CHECK
ALTER TABLE items ADD CONSTRAINT chk_uuid CHECK (
id REGEXP '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$'
);
SELECT UUID(); -- v1
SELECT UUID_TO_BIN(UUID(), 1); -- байты v1 с перестановкой для сортировки
PostgreSQL
-- Проверка регулярным выражением
SELECT '550e8400-e29b-41d4-a716-446655440000'
~ '^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$';
-- Лучше использовать родной тип: PostgreSQL 18 сам выдаёт детали
SELECT uuid_extract_version('018f3b7a-9c2d-7f41-a1b2-c3d4e5f60718'); -- 7
Частые вопросы
Почему шаблон принимает явно неверные UUID?
Обычно потому, что ниблы версии и варианта оставлены как [0-9a-f] — это мягкий шаблон. Поставьте [1-8] для 13-го символа и [89ab] для 17-го, и невозможные значения начнут отклоняться.
Какой шаблон выбрать?
Строгий — для валидации ввода и ограничений в базе; мягкий — только когда нужно найти похожие на UUID токены в свободном тексте, где допустим нестандартный вариант.
Совпадение доказывает, что UUID существует?
Нет. Регулярное выражение проверяет только строку. Существует ли идентификатор в вашей системе — отдельный вопрос, требующий выборки данных.