Баш точка. в группе [] - PullRequest
       3

Баш точка. в группе []

0 голосов
/ 04 июня 2019

Мне нужна была возможность быстро перейти из каталога к одному из его предков с именем, соответствующим конкретному регулярному выражению. Я понял, что могу использовать expr match для выбора определенной части pwd, а затем cd внутри. Затем я добавил бы простой скрипт в качестве псевдонима в .bashrc и назвал бы его день. По сути, мне пришлось выбрать .../WoRd*/ что-то вроде /some/directory/path/WoRd.to-match_x/hello/world/.

Итак, я написал регулярное выражение для этого - '\(.*/[wW][oO][rR][dD][a-zA-Z0-9_-.]*/\)' - но это не сработало. Он выбрал всю строку вместо части с "... / WorD /".

$ str="/some/directory/path/WoRd.to-match_x/hello/world/"
$ echo "match: " $(expr match "$str" '\(.*/[wW][oO][rR][dD][a-zA-Z0-9_-.]*/\)');
match:  /some/directory/path/WoRd.to-match_x/hello/world/

Затем я попытался замаскировать точку, но это не помогло:

$ echo "match: " $(expr match "$str" '\(.*/[wW][oO][rR][dD][a-zA-Z0-9_-\.]*/\)');
match:  /some/directory/path/WoRd.to-match_x/hello/world/

Час или около того поиск в Google и чтение руководств по регулярным выражениям не помогли.

Мне действительно удалось заставить эту вещь работать, переместив точку влево:

$ echo "match: " $(expr match "$str" '\(.*/[wW][oO][rR][dD][a-zA-Z0-9_.-]*/\)');
match:  /some/directory/path/WoRd.to-match_x/

Моя версия bash: GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)

Кто-нибудь знает, почему это происходит?

1 Ответ

3 голосов
/ 04 июня 2019

Точка не проблема.Все символы внутри выражения в скобках обрабатываются буквально ... за исключением -.

Ваши последние 3 символа, _-., определяют диапазон, состоящий из (в порядке ASCII) символов, начинающихся с _ изаканчивающийся ..Поскольку _ - это ASCII 95, а . - это ASCII 46, диапазон пуст, поэтому ваше регулярное выражение эквивалентно '\(.*/[wW][oO][rR][dD][a-zA-Z0-9]*/\)'.

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

Кроме того, вам не нужно использовать expr для сопоставления регулярных выражений в bash.

regex='(.*/[wW][oO][rR][dD][[:alnum:]_.-]*/)'
[[ $str =~ $regex ]]
echo "match: ${BASH_REMATCH[1]}"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...