Вопрос:

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

regex bash quotes

32373 просмотра

4 ответа

1163 Репутация автора

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

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.

Автор: tpk Источник Размещён: 20.10.2008 11:53

Ответы (4)


112 плюса

213820 Репутация автора

Решение

Это было изменено между 3.1 и 3.2 . Угадай, продвинутый гид нуждается в обновлении.

Это краткое описание новых функций, добавленных в bash-3.2 с момента выпуска bash-3.1. Как всегда, страница справочника (doc / bash.1) - место для поиска полных описаний.

  1. Новые функции в Bash

надрез

е. Заключение строкового аргумента в оператор [[command's = ~] теперь вызывает сопоставление строк, как и в случае других операторов сопоставления с образцом.

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

$ 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
Автор: Vinko Vrsalovic Размещён: 20.10.2008 12:15

19 плюса

8560 Репутация автора

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

Автор: Nicholas Sushkin Размещён: 27.06.2011 07:00

7 плюса

9665 Репутация автора

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
Автор: Ankur Agarwal Размещён: 10.09.2013 08:33

5 плюса

12108 Репутация автора

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

$ number=1
$ if [[ $number =~ $(echo "[0-9]") ]]; then echo matched; fi
matched
$ 
Автор: Digital Trauma Размещён: 13.02.2014 06:34
Вопросы из категории :
32x32