Є кілька важливих речей, які слід знати про [[ ]]
будівництво Баша . Перший:
Розбиття слів і розширення імені шляху не виконуються для слів між [[
і ]]
; виконуються розширення тильди, розширення параметрів та змінних, арифметичне розширення, підстановка команд, заміна процесів та видалення котирувань.
Друге:
Доступний додатковий двійковий оператор, '= ~', ... рядок праворуч від оператора вважається розширеним регулярним виразом і відповідно відповідає йому ... Будь-яка частина шаблону може бути вказана в лапках, щоб змусити його відповідати як рядок .
Отже, $v
по обидві сторони =~
буде розширено до значення цієї змінної, але результат не буде розділений словом або розширений за допомогою шляху. Іншими словами, абсолютно безпечно залишати змінні розширення без лапок зліва, але ви повинні знати, що розширення змінних відбуватимуться з правого боку.
Так що якщо ви пишете: [[ $x =~ [$0-9a-zA-Z] ]]
, то $0
в регулярному виразі по праву буде розширено до регулярного виразу інтерпретується, який, ймовірно , викличе регулярний вираз , щоб не компілювати (якщо не вказано розширення $0
цілей з символом цифр або знаків пунктуації , чиє ASCII значення менше цифра). Якщо ви цитуєте праву сторону так [[ $x =~ "[$0-9a-zA-Z]" ]]
, то права сторона буде розглядатися як звичайний рядок, а не як регулярний вираз (і $0
все одно буде розширена). Що ви справді хочете в цьому випадку, так це[[ $x =~ [\$0-9a-zA-Z] ]]
Подібним чином вираз між символами [[
та ]]
поділяється на слова перед інтерпретацією регулярного виразу . Отже, місця в регулярному виразі потрібно уникати або вводити їх у лапки. Якщо ви хочете , щоб відповідати букви, цифри та пробіли ви можете використовувати: [[ $x =~ [0-9a-zA-Z\ ] ]]
. Інших символів так само потрібно уникнути, наприклад #
, що б почало коментар, якщо не цитувати. Звичайно, ви можете помістити шаблон у змінну:
pat="[0-9a-zA-Z ]"
if [[ $x =~ $pat ]]; then ...
Для регулярних виразів, які містять безліч символів, які потрібно було б уникнути або процитувати, щоб пройти через лексер bash, багато людей віддають перевагу цьому стилю. Але будьте обережні: у цьому випадку ви не можете вказати розширення змінної:
if [[ $x =~ "$pat" ]]; then ...
Нарешті, я думаю, що ви намагаєтеся зробити, це переконатися, що змінна містить лише допустимі символи. Найпростіший спосіб зробити цю перевірку - переконатися, що вона не містить недопустимого символу. Іншими словами, такий вираз:
valid='0-9a-zA-Z $%&#'
if [[ ! $x =~ [^$valid] ]]; then ...
!
заперечує тест, перетворюючи його на оператор "не відповідає", а [^...]
клас символів регулярного виразу означає "будь-який інший символ, крім ...
".
Поєднання операторів розширення параметрів та регулярних виразів може зробити синтаксис регулярних виразів bash "майже читабельним", але все ж є деякі помилки. (Не існує завжди?) По- перше, ви не могли б поставити ]
в $valid
, навіть якщо $valid
були вказані, за винятком самого початку. (Це правило регулярного виразу Posix: якщо ви хочете долучитись ]
до класу символів, він повинен йти на початку. -
Може йти на початку або в кінці, тому, якщо вам потрібні обидва ]
і -
, вам потрібно починати з ]
і закінчувати -
, що призводить до регулярного виразу «я знаю , що я роблю» смайлик: [][-]
)