2015-12-23 2 views
0
[email protected]:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$ ]] && echo LIB 
LIB 
[email protected]:~$ echo ${#BASH_REMATCH[*]} 
3 
[email protected]:~$ echo ${BASH_REMATCH[1]} 
.0.8.4 
[email protected]:~$ echo ${BASH_REMATCH[2]} 
.4 

Можно найти работы и библиотечную версию Regex.Иррациональный шаблон REGEX, соответствующий в Bash

[email protected]:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$|^lib.+[.]so.* ]] && echo LIB 
LIB 
[email protected]:~$ echo ${#BASH_REMATCH[*]} 
3 
[email protected]:~$ echo "'${BASH_REMATCH[1]}'" 
'' 
[email protected]:~$ echo "'${BASH_REMATCH[2]}'" 
'' 

Спички, но версия безвозвратная.

[email protected]:~$ [[ "libSDL_image-1.2.so.0.8.4" =~ ^.*[.]so(([.][0-9]+)+)*$|^lib.+[.]so(.*) ]] && echo LIB 
LIB 
[email protected]:~$ echo ${#BASH_REMATCH[*]} 
4 
[email protected]:~$ echo "'${BASH_REMATCH[1]}'" 
'' 
[email protected]:~$ echo "'${BASH_REMATCH[2]}'" 
'' 
[email protected]:~$ echo "'${BASH_REMATCH[3]}'" 
'.0.8.4' 

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

Вопрос в том, почему первое совпадение игнорируется, и есть ли способ сказать, когда альтернатива будет соответствовать последовательности?

+0

Это работает, как вы, кажется, рассчитывать на меня в Баш 3.2.48 (на OS X), но не 4.2.37 (на Debian). – Barmar

+0

работает в osx в '4.3.42 (1) -release (x86_64-apple-darwin15.0.0)' (macports) также в '4.3.33 (0) -release (amd64-portbld-freebsd9.0)'. – jm666

+0

OT: Я не понимаю '*' in '(([.] [0-9] +) +) *'. То, к чему это относится, уже повторяется, поэтому все, что '*' делает, делает его необязательным. Но тогда вы могли бы просто использовать необязательный повтор в первую очередь: '(([.] [0-9] +) *)'. Я не думаю, что это влияет на то, как чередование сопоставляется (хотя вы никогда не знаете), но всегда полезно избегать бессмысленных операторов повторения. – rici

ответ

1

Posix не определяет предпочтения между узорами в чередовании |

Posix требует (т.е. шаблон регулярного выражения с в качестве основного оператора.):

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

  • , что каждый подшаблон слева направо должен быть как можно дольше, в пределах оставшихся возможностей.

Это совершенно отличается от (традиционного) Perl и ECMAScript, которые требуют, чтобы чередования быть судимыми в порядке, и что успех альтернативы предпочтительнее следующих альтернативы, даже если следующие альтернативы будут больше.

Это всего лишь два способа определения соответствия регулярных выражений. Я не думаю, что это более «рационально»; есть хорошие аргументы для каждого и против каждого, и в конечном счете нужно выбрать.

Модель Posix ближе к математической модели для обычных языков, для чего она стоит.

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

Ваш лучший выбор - позволить использовать любой захват. Например, (используя третий пример):

version=${BASH_REMATCH[2]:-${BASH_REMATCH[3]}} 
+0

Имейте в виду, что сам 'bash' не указывает, какие регулярные выражения он использует. Вместо этого '= ~' использует любую библиотеку регулярных выражений базовой системы. – chepner

+0

@chepner: в руководстве bash говорится: «строка справа от оператора считается расширенным регулярным выражением и соответствующим образом соответствует (как в regex3))». Я не вижу способа интерпретировать эту ссылку на ERE со ссылкой на справочную страницу posix каким-либо другим способом, чем регулярные выражения posix. – rici

+0

Это техничность, но факт остается фактом: 'bash' не поставляется с собственным движком регулярных выражений и зависит от ОС, чтобы обеспечить его. 'bash' сам по себе не может абсолютно гарантировать переносимое поведение. (Да, я, вероятно, чересчур педантичен.) – chepner

Смежные вопросы