#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Що робить провідний ~
у вихідному регулярному виразі?
#!/bin/bash
INT=-5
if [[ "$INT" =~ ^-?[0-9]+$ ]]; then
echo "INT is an integer."
else
echo "INT is not an integer." >&2
exit 1
fi
Що робить провідний ~
у вихідному регулярному виразі?
Відповіді:
Фактично, ~
це частина оператора, =~
яка виконує відповідність регулярного вираження рядка зліва з розширеним регулярним виразом праворуч.
[[ "string" =~ pattern ]]
Зауважте, що рядок слід цитувати, а регулярний вираз не повинен цитувати.
Аналогічний оператор використовується в мові програмування Perl.
Регулярні вирази, що розуміються, bash
такі ж, як і GNU, які grep
розуміють із -E
прапором, тобто розширений набір регулярних виразів.
Дещо поза темою, але добре знати:
При зіставленні з регулярним виразом, що містить групи захоплення, частина рядка, захоплена кожною групою, доступна в BASH_REMATCH
масиві. Нульовий / перший запис у цьому масиві відповідає &
шаблону заміни команди sed
"заміщення" (або $&
в Perl), що є бітом рядка, що відповідає шаблону, тоді як записи в індексі 1 і далі відповідають \1
, \2
і т.д. . в sed
шаблоні заміни (або $1
, і $2
т.д. в Perl), тобто біти збігаються кожної дужкою.
Приклад:
string=$( date +%T )
if [[ "$string" =~ ^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$ ]]; then
printf 'Got %s, %s and %s\n' \
"${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
fi
Це може вивести
Got 09, 19 and 14
якщо поточний час стане 09:19:14.
REMATCH
Біт BASH_REMATCH
імені масиву походить від «регулярного виразу», тобто «RE-Match».
У не- bash
Bourne-подібних оболонках можна також використовувати expr
обмежене регулярне узгодження виразів (використовуючи лише основні регулярні вирази).
Невеликий приклад:
$ string="hello 123 world"
$ expr "$string" : ".*[^0-9]\([0-9][0-9]*\)"
123
grep -E
розуміється лише в системах GNU і тільки при використанні змінної без котирування в якості шаблону [[ $var = $pattern ]]
(див. [[ 'a b' =~ a\sb ]]
Vs p='a\sb'; [[ 'a b' =~ $p ]]
). Також майте на увазі, що котирування оболонки впливає на значення RE-операторів і що деякі символи повинні бути цитовані для маркування оболонки, яке може вплинути на обробку RE. [[ '\' =~ [\/] ]]
повертає помилкове. ksh93
має ще гірші проблеми. Дивіться zsh
(або bash 3.1) для більш безпечного підходу, коли цитування оболонки та RE чітко розділені. [
Вбудований в zsh
а yash
також =~
оператор.
off-topic
! +1 (
[[ "This is a fine mess." =~ T.........fin*es* ]]; [[ "This is a fine mess." =~ T.........fin\*es\* ]]
. Або що цитується *
також збігається? [[ "This is a fine mess." =~ "T.........fin*es*" ]]
.
[[ a =~ .* ]]
або [[ a =~ '.*' ]]
або [[ a =~ \.\* ]]
, то ж .*
RE передається =~
оператору. ДЕЙ, в bash
, [[ '\' =~ [)] ]]
повертає помилку, чи знаєте ви, не намагаючись це [[ '\' =~ [\)] ]]
відповідати? Як щодо [[ '\' =~ [\/] ]]
(це в ksh93). Як щодо c='a-z'; [[ a =~ ["$c"] ]]
(порівняйте з =
оператором)? Дивіться також: [[ '\' =~ [^]"."] ]]
який повертає помилкове ... Зверніть увагу , що ви можете зробити shopt -s compat31
в , bash
щоб отримати zsh
поведінку.
zsh
/ bash -o compat31
'поведінка для [[ a =~ '.*' ]]
також відповідає [ a '=~' '.*' ]
(для [
реалізацій, які підтримують =~
) або expr a : '.*'
. OTOH, це не відповідає [[ a = '*' ]]
vs [[ a = * ]]
(але тоді, глобуси є частиною мови оболонки, тоді як RE - ні).
Ви повинні прочитати сторінки bash man під [[ expression ]]
розділом.
An additional binary operator, =~, is available, with the same precedence as == and !=. When it is used, the string to the right of the operator is considered an extended regular expression and matched accordingly (as in regex(3)).
Коротше кажучи, =~
це оператор, як ==
і !=
. Це не має нічого спільного з фактичним регулярним виразом у рядку праворуч.
=~
в реальному житті ...?
man [[ expresssion ]]
ні і man [[
повернення нічого. help [[
повертає корисну інформацію - починаючи [[
з внутрішньої команди bash - але не говорить про те, =~
використовує базовий чи розширений синтаксис регулярних виразів. ⋯ Текст, який ви цитуєте, зі сторінки bash man. Я усвідомлюю, що ви сказали «читайте сторінки bash man», але спочатку я подумав, що ви маєте на увазі прочитати сторінки чоловіка в bash. У будь-якому випадку, man bash
повертає величезний файл, протяжністю 4139 рядків (72 сторінки). У ньому можна шукати натисканням /▒▒▒
, яке займає регулярний вираз, аромат якого - як-от =~
- не вказано.