#!/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».
У не- bashBourne-подібних оболонках можна також використовувати 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 сторінки). У ньому можна шукати натисканням /▒▒▒, яке займає регулярний вираз, аромат якого - як-от =~- не вказано.