2016-03-04 2 views
1

Я не могу это объяснить, но проверьте следующее:Почему это регулярное выражение соответствует почти всему?

name=$1 
pat="\b[0-9a-zA-Z_]+\b" 

if [[ $name =~ $pat ]]; then 
    echo "$name is ok as user name" 
else 
    echo "$name is not ok as user name" 
    exit 1 
fi 

Тестовый прогон:

./script test_user+ 
test_user+ is ok as user name 

Имя пользователя, с + знак не должно совпадать с регулярным выражением.

+1

Почему так много downvotes по этому вопросу? – anubhava

+0

btw [ваш скрипт отлично работает] (http://ideone.com/nzagNv) ** без каких-либо изменений ** – anubhava

+0

Мне любопытно также количество downvotes. Это хороший вопрос. – jkdba

ответ

5

Прежде всего:

\b является расширение PCRE; он недоступен в ERE, который использует оператор =~ в синтаксисе [[ ]] bash.

(от Bash regex match with word boundary)

Во-вторых, вы не хотите словоразделы (\b), если вы хотите, чтобы заставить всю строку, чтобы соответствовать. Вы хотите, чтобы соответствовать начало (^) и конец ($):

pat="^[0-9a-zA-Z_]+\$" 
+1

Большое вам спасибо, действительно, это проблема. – Istvan

0

если вы не хотите слово bondry (догадались, как вы пытаетесь матч имя пользователя), пожалуйста, используйте

^[0-9a-zA-Z_]+$ 
0

В отличие от ФП-х опыт и другой ответ кажется \b поддерживается на Ubuntu 14.04, bash 4.3.11 как граница слова. Вот пример:

re='\bb[0-9]+\b' 

[[ 'b123' =~ $re ]] && echo "matched" || echo "nope" 
matched 

[[ 'b123_' =~ $re ]] && echo "matched" || echo "nope" 
nope 

Даже \< и \> также прекрасно работают словоразделами:

re='\<b[0-9]+\>' 

[[ 'b123' =~ $re ]] && echo "matched" || echo "nope" 
matched 

[[ 'b123_' =~ $re ]] && echo "matched" || echo "nope" 
nope 

Однако поддержка \b специфичен только определенной ОС. например на OSX после работает как граница слова:

[[ 'b123' =~ [[:\<:]]b[0-9]+[[:\>:]] ]] && echo "matched" || echo "nope" 
matched 

[[ 'b123_' =~ [[:\<:]]b[0-9]+[[:\>:]] ]] && echo "matched" || echo "nope" 
nope 
Смежные вопросы