Необязательные параметры в регулярном выражении Bash - PullRequest
6 голосов
/ 04 января 2012

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

Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";

или

Category: resource;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Resource";rel="http://schemas.ogf.org/occi/core#entity";attributes="occi.core.summary";

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

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

Вот что я достиг на данный момент:

CATEGORY_REGEX='Category:\s*([^;]*);scheme="([^"]*)";class="([^"]*)";'
category_string='Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";'
[[ $category_string =~ $CATEGORY_REGEX ]]
echo ${BASH_REMATCH[0]}
echo ${BASH_REMATCH[1]}
echo ${BASH_REMATCH[2]}
echo ${BASH_REMATCH[3]}

Регулярное выражение, которое я хотел бы использовать (и которое работает для меня в Ruby):

CATEGORY_REGEX='Category:\s*([^;]*);\s*scheme="([^"]*)";\s*class="([^"]*)";\s*(?:title="([^"]*)";)?\s*(?:rel="([^"]*)";)?\s*(?:location="([^"]*)";)?\s*(?:attributes="([^"]*)";)?\s*(?:actions="([^"]*)";)?'

Есть ли другое решение для анализа строки с помощью инструментов командной строки без необходимости использовать perl, python или ruby?

Ответы [ 2 ]

8 голосов
/ 04 января 2012

Я не думаю, что в bash regex существуют группы без захвата, поэтому вы можете использовать язык сценариев или удалить ?: из всех групп (?:...) и просто быть осторожным в отношении тех групп, на которые вы ссылаетесьНапример:

CATEGORY_REGEX='Category:\s*([^;]*);\s*scheme="([^"]*)";\s*class="([^"]*)";\s*(title="([^"]*)";)?\s*(rel="([^"]*)";)?\s*(location="([^"]*)";)?\s*(attributes="([^"]*)";)?\s*(actions="([^"]*)";)?'
category_string='Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";'
[[ $category_string =~ $CATEGORY_REGEX ]]
echo "full:       ${BASH_REMATCH[0]}"
echo "category:   ${BASH_REMATCH[1]}"
echo "scheme:     ${BASH_REMATCH[2]}"
echo "class:      ${BASH_REMATCH[3]}"
echo "title:      ${BASH_REMATCH[5]}"
echo "rel:        ${BASH_REMATCH[7]}"
echo "location:   ${BASH_REMATCH[9]}"
echo "attributes: ${BASH_REMATCH[11]}"
echo "actions:    ${BASH_REMATCH[13]}"

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

0 голосов
/ 03 октября 2016

Вы можете эмулировать несоответствующие группы в bash, используя немного магии регулярных выражений:

              _2__    _4__   _5__
[[ "fu@k" =~ ((.+)@|)((.+)/|)(.+) ]];
echo "${BASH_REMATCH[2]:--} ${BASH_REMATCH[4]:--} ${BASH_REMATCH[5]:--}"
# Output: fu - k

Символы @ и / являются частями разбираемой строкиКанал регулярных выражений | используется для сопоставления левой или правой (пустой) части.

Для любопытных, ${VAR:-<default value>} - это расширение переменной со значением по умолчанию в случае, если $ VAR пусто.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...