que quiero analizar cadenas similares a los siguientes en variables separadas usando expresiones regulares dentro de Bash:parámetros opcionales en Bash expresión regular
Category: entity;scheme="http://schemas.ogf.org/occi/core#";class="kind";title="Entity";attributes="occi.core.id occi.core.title";
o
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";
La primera parte antes de "título" es común a todas las cadenas, el título y los atributos de las partes son opcionales.
Logré extraer los parámetros obligatorios comunes a todas las cadenas, pero tengo problemas con los parámetros opcionales no necesariamente presentes para todas las cadenas. Por lo que descubrí, Bash no es compatible con paréntesis de no captura que usaría para este propósito.
Aquí es lo que he logrado hasta el momento:
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]}
La expresión regular me gustaría utilizar (y que está trabajando para mí en Ruby) sería:
CATEGORY_REGEX='Category:\s*([^;]*);\s*scheme="([^"]*)";\s*class="([^"]*)";\s*(?:title="([^"]*)";)?\s*(?:rel="([^"]*)";)?\s*(?:location="([^"]*)";)?\s*(?:attributes="([^"]*)";)?\s*(?:actions="([^"]*)";)?'
¿Hay alguna otra solución para analizar la cadena con herramientas de línea de comandos sin tener que recurrir a perl, python o ruby?
Eso de hecho está funcionando. No es la solución más elegante, pero siempre que no haya grupos no capturadores en bash, la solución alternativa de saltear un grupo cada vez es probablemente la mejor solución. Una cosa todavía me molesta: si hay espacios detrás de cualquier punto y coma, la expresión regular falla incluso así hay patrones "\ s *" detrás de ellos para que coincida con espacios en blanco. –
Parece que los caracteres especiales como "\ s *" no funcionan. Sustituirlo con solo un espacio funcionó: "\ s *" => "*" –
Intenta usar [[: espacio:]] * en lugar de \ s. –