Вопрос или проблема
Я хочу использовать regex
для проверки только трех разрешенных символов: “[0-9]
“, “.
” и “/
“.
Примечание: Тестовый случай – это ipv4/ipv6
адрес, но я не хочу проверять число в диапазоне [0-255]
, я только хочу проверить разрешенные символы в переменной ввода.
Я использую “|
” как выражение “или” и комбинирую все три разрешенных символа с “|
“, а затем добавляю “+
” в конце, чтобы убедиться, что по крайней мере один разрешенный символ должен существовать в переменной ввода.
Вот тестовый bash-скрипт:
test_ipv4_address="127.0.0.1/24"
test_wrong_ipv4_address="127.0.0.1#24"
test_ipv6_address="::1/128"
allowed_characters="([0-9]|\.|\/)+"
[[ "$test_ipv4_address" =~ $allowed_characters ]] && echo "да, $test_ipv4_address разрешен"
[[ "$test_wrong_ipv4_address" =~ $allowed_characters ]] && echo "да, $test_wrong_ipv4_address разрешен"
[[ "$test_ipv6_address" =~ $allowed_characters ]] && echo "да, $test_ipv6_address разрешен"
Вот вывод:
да, 127.0.0.1/24 разрешен
да, 127.0.0.1#24 разрешен
да, ::1/128 разрешен
Вот ожидаемый вывод:
да, 127.0.0.1/24 разрешен
Что не так в моем regex? И как это исправить?
Ваше регулярное выражение кажется почти правильным, но ему нужны небольшие корректировки:
- Символ
.
в regex имеет специальное значение (соответствует любому символу), поэтому его нужно экранировать с помощью\.
, чтобы соответствовать буквальным точкам. - Вы уже правильно экранировали
.
, но ключевая проблема в том, как вы обрабатываете regex в bash. Bash обрабатывает regex иначе, чем другие языки, поэтому дважды проверьте, как он применяется.
Теперь модифицированный скрипт будет выглядеть примерно так:
test_ipv4_address="127.0.0.1/24"
test_wrong_ipv4_address="127.0.0.1#24"
test_ipv6_address="::1/128"
# Regex для разрешения только цифр, точек и слэшей
allowed_characters="^[0-9./]+$"
# Проверка, соответствует ли ввод разрешенным символам
[[ "$test_ipv4_address" =~ $allowed_characters ]] && echo "да, $test_ipv4_address разрешен"
[[ "$test_wrong_ipv4_address" =~ $allowed_characters ]] && echo "да, $test_wrong_ipv4_address разрешен"
[[ "$test_ipv6_address" =~ $allowed_characters ]] && echo "да, $test_ipv6_address разрешен"
И вы получите желаемый вывод, похожий на этот:
└─$ ./test.sh
да, 127.0.0.1/24 разрешен
Ответ или решение
Чтобы проверить разрешённые символы в строке с использованием регулярных выражений (regex) в Bash, важно учитывать специфику синтаксиса и поведения регулярных выражений в этой среде. В вашем случае вы хотите допустить только три типа символов: цифры (0-9), точку (.) и косую черту (/). Рассмотрим, как правильно реализовать эту проверку, избегая распространённых ошибок.
Проблема с вашим регулярным выражением
Вы использовали следующее регулярное выражение в вашем Bash-скрипте:
allowed_characters="([0-9]|\.|\/)+"
Здесь есть несколько важных моментов:
-
Специфика символа точки: В регулярных выражениях символ
.
является специальным символом, который соответствует любому одиночному символу. Чтобы указать обработку точки как простого символа, необходима экранирование:\.
. Важно избегать путаницы с синтаксисом, поэтому точка должна быть правильно экранирована. -
Использование метасимволов: Ваша конструкция с использованием
|
(логическое ИЛИ) не оптимальна в контексте bash. Вместо этого лучше воспользоваться эквивалентом, который проверяет соответствие всей строки. -
Проверка всей строки: Вам нужно модифицировать регулярное выражение так, чтобы оно соответствовало всей строке. Использование символов начала
^
и конца$
поможет убедиться, что строка полностью состоит из допустимых символов.
Исправленный скрипт
Вот как можно изменить ваш Bash-скрипт для правильной проверки допустимых символов:
test_ipv4_address="127.0.0.1/24"
test_wrong_ipv4_address="127.0.0.1#24"
test_ipv6_address="::1/128"
# Регулярное выражение для разрешённых символов: цифры, точки и косые черты
allowed_characters="^[0-9./]+$"
# Проверка на соответствие введенной строки разрешённым символам
[[ "$test_ipv4_address" =~ $allowed_characters ]] && echo "yes, $test_ipv4_address is allowed"
[[ "$test_wrong_ipv4_address" =~ $allowed_characters ]] && echo "yes, $test_wrong_ipv4_address is allowed"
[[ "$test_ipv6_address" =~ $allowed_characters ]] && echo "yes, $test_ipv6_address is allowed"
Ожидаемый вывод
После внесения этих правок, вы можете запустить скрипт и получить следующий результат:
yes, 127.0.0.1/24 is allowed
Заключение
Проверка допустимых символов в строке — это важный аспект обработки данных в Bash. Исправив регулярное выражение и корректно указав границы строки, вы сможете избежать ошибок, связанных с недопустимыми символами. Используйте подходы выше для эффективной работы с строками и регулярными выражениями, что в конечном итоге улучшит надежность вашего кода.