В bash оператор [[ string =~ regex ]] дает инструмент для проверки строк по регулярным выражениям. Но у него есть особенности, о которых часто забывают.
▪️ Базовый синтаксис
str="user123"
if [[ $str =~ ^user[0-9]+$ ]]; then
echo "Совпало"
else
echo "Нет совпадения"
fi
=~ - оператор сравнения по регулярному выражению (ERE)
без кавычек вокруг regex (!), иначе он станет строкой
▪️ Подводные камни
1️⃣ Кавычки ломают regex
[[ $str =~ "^[0-9]+$" ]] # НЕ работает как regex
[[ $str =~ ^[0-9]+$ ]] # правильно
2️⃣ Пробелы в regex → нужно экранировать
[[ "foo bar" =~ foo\ bar ]] # правильно
3️⃣ Группы и BASH_REMATCH
str="id=42 user=admin"
if [[ $str =~ id=([0-9]+)\ user=([a-z]+) ]]; then
echo "ID: ${BASH_REMATCH[1]}"
echo "User: ${BASH_REMATCH[2]}"
fi
BASH_REMATCH[0] - вся строка, [1]..[n] — группы.
4️⃣ Regex всегда интерпретируется как ERE (Extended Regex)
+, ?, | работают без \
Но нет поддержки PCRE (\d, \w, lookahead и т.п.)
5️⃣ Неочевидные совпадения из-за пустого паттерна
regex="^$" # пустая строка
[[ "abc" =~ $regex ]] && echo "совпало" # неожиданно не совпадает
6️⃣ Вложенные переменные в regex. Если подставлять переменную в regex, лучше использовать () для контроля:
re="[0-9]{2}"
[[ "2025" =~ ($re) ]] && echo "нашли: ${BASH_REMATCH[1]}"
▪️ Полезные приемы
1️⃣ Проверка на число:
[[ $x =~ ^[0-9]+$ ]] && echo "число"
2️⃣ Проверка на IPv4:
[[ $ip =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] && echo "ipv4"
3️⃣ Проверка на slug (латиница, цифры, дефис):
[[ $slug =~ ^[a-z0-9-]+$ ]] || echo "некорректный slug"
BashTex 📱 #bash