Как проверить допустимые символы в bash с помощью регулярных выражений

Вопрос или проблема

Я хочу использовать 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? И как это исправить?

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

  1. Символ . в regex имеет специальное значение (соответствует любому символу), поэтому его нужно экранировать с помощью \., чтобы соответствовать буквальным точкам.
  2. Вы уже правильно экранировали ., но ключевая проблема в том, как вы обрабатываете 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]|\.|\/)+"

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

  1. Специфика символа точки: В регулярных выражениях символ . является специальным символом, который соответствует любому одиночному символу. Чтобы указать обработку точки как простого символа, необходима экранирование: \.. Важно избегать путаницы с синтаксисом, поэтому точка должна быть правильно экранирована.

  2. Использование метасимволов: Ваша конструкция с использованием | (логическое ИЛИ) не оптимальна в контексте bash. Вместо этого лучше воспользоваться эквивалентом, который проверяет соответствие всей строки.

  3. Проверка всей строки: Вам нужно модифицировать регулярное выражение так, чтобы оно соответствовало всей строке. Использование символов начала ^ и конца $ поможет убедиться, что строка полностью состоит из допустимых символов.

Исправленный скрипт

Вот как можно изменить ваш 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. Исправив регулярное выражение и корректно указав границы строки, вы сможете избежать ошибок, связанных с недопустимыми символами. Используйте подходы выше для эффективной работы с строками и регулярными выражениями, что в конечном итоге улучшит надежность вашего кода.

Оцените материал
Добавить комментарий

Капча загружается...