Регулярное выражение bash с кавычками?

Следующий код

number=1
if [[ $number =~ [0-9] ]]
then
  echo matched
fi

работает. Однако если я попытаюсь использовать кавычки в регулярном выражении, оно остановится:

number=1
if [[ $number =~ "[0-9]" ]]
then
  echo matched
fi

Я тоже пробовал "\[0-9\]". Что мне не хватает?

Как ни странно, bash расширенное руководство по написанию сценариев предполагает, что это должно сработать.

Bash версии 3.2.39.

АБС довольно печально известна как источник неточных (или, в лучшие дни, просто вводящих в заблуждение) указаний; считайте это школой W3Schools сценариев оболочки. Рассматривайте bash-hackers.org или wooledge wiki как альтернативу, поддерживаемую с учетом точности.

Charles Duffy 15.07.2016 00:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
77
1
35 308
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Был изменен между 3,1 и 3,2. Думаю, для расширенного руководства нужно обновление.

This is a terse description of the new features added to bash-3.2 since the release of bash-3.1. As always, the manual page (doc/bash.1) is the place to look for complete descriptions.

  1. New Features in Bash

snip

f. Quoting the string argument to the [[ command's =~ operator now forces string matching, as with the other pattern-matching operators.

К сожалению, это нарушит существующую цитату с использованием сценариев, если у вас нет понимания, как хранить шаблоны в переменных и напрямую использовать их вместо регулярных выражений. Пример ниже.

$ bash --version
GNU bash, version 3.2.39(1)-release (i486-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
$ if [[ $number =~ [0-9] ]]; then echo match; fi
match
$ re = "[0-9]"
$ if [[ $number =~ $re ]]; then echo MATCH; fi
MATCH

$ bash --version
GNU bash, version 3.00.0(1)-release (i586-suse-linux)
Copyright (C) 2004 Free Software Foundation, Inc.
$ number=2
$ if [[ $number =~ "[0-9]" ]]; then echo match; fi
match
$ if [[ "$number" =~ [0-9] ]]; then echo match; fi
match

Это настоящее развлечение. Цитированные регулярные выражения больше не работают. Регулярные выражения без кавычек с пробелами не работают. Регулярные выражения на основе переменных работают, даже если они содержат пробелы. Какой беспорядок.

Pavel Šimerda 30.10.2016 01:25

Bash 3.2 представил параметр совместимости compat31, который возвращает поведение цитирования регулярных выражений bash обратно к 3.1.

Без compat31:

$ shopt -u compat31
$ shopt compat31
compat31        off
$ set -x
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ \[0-9] ]]
+ echo no match
no match

С compat31:

$ shopt -s compat31
+ shopt -s compat31
$ if [[ "9" =~ "[0-9]" ]]; then echo match; else echo no match; fi
+ [[ 9 =~ [0-9] ]]
+ echo match
match

Ссылка на патч: http://ftp.gnu.org/gnu/bash/bash-3.2-patches/bash32-039

GNU bash, версия 4.2.25 (1) -релиз (x86_64-pc-linux-gnu)

Некоторые примеры совпадений строк и регулярных выражений

    $ if [[ 234 =~ "[0-9]" ]]; then echo matches;  fi # string match
    $ 

    $ if [[ 234 =~ [0-9] ]]; then echo matches;  fi # regex natch 
    matches


    $ var = "[0-9]"

    $ if [[ 234 =~ $var ]]; then echo matches;  fi # regex match
    matches


    $ if [[ 234 =~ "$var" ]]; then echo matches;  fi # string match after substituting $var as [0-9]

    $ if [[ 'rss$var919' =~ "$var" ]]; then echo matches;  fi   # string match after substituting $var as [0-9]

    $ if [[ 'rss$var919' =~ $var ]]; then echo matches;  fi # regex match after substituting $var as [0-9]
    matches


    $ if [[ "rss\$var919" =~ "$var" ]]; then echo matches;  fi # string match won't work

    $ if [[ "rss\\$var919" =~ "$var" ]]; then echo matches;  fi # string match won't work


    $ if [[ "rss'$var'""919" =~ "$var" ]]; then echo matches;  fi # $var is substituted on LHS & RHS and then string match happens 
    matches

    $ if [[ 'rss$var919' =~ "\$var" ]]; then echo matches;  fi # string match !
    matches



    $ if [[ 'rss$var919' =~ "$var" ]]; then echo matches;  fi # string match failed
    $ 

    $ if [[ 'rss$var919' =~ '$var' ]]; then echo matches;  fi # string match
    matches



    $ echo $var
    [0-9]

    $ 

    $ if [[ abc123def =~ "[0-9]" ]]; then echo matches;  fi

    $ if [[ abc123def =~ [0-9] ]]; then echo matches;  fi
    matches

    $ if [[ 'rss$var919' =~ '$var' ]]; then echo matches;  fi # string match due to single quotes on RHS $var matches $var
    matches


    $ if [[ 'rss$var919' =~ $var ]]; then echo matches;  fi # Regex match 
    matches
    $ if [[ 'rss$var' =~ $var ]]; then echo matches;  fi # Above e.g. really is regex match and not string match
    $


    $ if [[ 'rss$var919[0-9]' =~ "$var" ]]; then echo matches;  fi # string match RHS substituted and then matched
    matches

    $ if [[ 'rss$var919' =~ "'$var'" ]]; then echo matches;  fi # trying to string match '$var' fails


    $ if [[ '$var' =~ "'$var'" ]]; then echo matches;  fi # string match still fails as single quotes are omitted on RHS 

    $ if [[ \'$var\' =~ "'$var'" ]]; then echo matches;  fi # this string match works as single quotes are included now on RHS
    matches

Как упоминалось в других ответах, размещение регулярного выражения в переменной - это общий способ достижения совместимости с разными версиями . Вы также можете использовать этот обходной путь для достижения того же результата, сохраняя свое регулярное выражение в условном выражении:

$ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$ 

Другие вопросы по теме