Trying to match some Gentoo package naming components from strings in forms category/name-version, due to its complexity, I have come to this:
if [[ "$1" =~ ^([<>]?=?)(([^\/]+)\/)?([^[:space:]]+)-(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?)?$ ]]; then
# use "${BASH_REMATCH[n]}" here to capture groups contents
fi
It splits strings like <category/package-name-12345.25b_rc10-r7
as expected:
Version specifier: <
Category: category
Package name: package-name
Version: 12345.25b_rc10-r7
Version, major: 12345
Version, minor: 25
Version, letter: b
Version, patch type: rc
Version, patch level: 10
Version, revision number: 7
Now, I need to match and split stings that may have version missing, like category/package-name
.
So, is there a way to make the version part above optional?
Above, this part is the following:
-(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?)?
I've tried to change it as:
(-(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+)))?))?
It works for a string without a version, but there seem that optional groups prevent it to match a slightly complete string like above and it gets:
Version specifier:
Category: category
Package name: package-name-12345.25b_rc10-r7
Version:
Version, major:
Version, minor:
Version, letter:
Version, patch type:
Version, patch level:
Version, revision number:
EDIT: Slots
What about two optional parts?
Additionally to the above, must match slots. Slots would be matched like this:
:(([[:digit:]]+)(\.([[:digit:]]+))*)?
Now, there are a category/name part:
([<>]?=?)(([^\/]+)\/)?([^[:space:]]+)
followed by either a version:
-(([[:digit:]]+)(\.([[:digit:]]+))*)([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?
a slot
:(([[:digit:]]+)(\.([[:digit:]]+))*)?
or both, version and slot, in this order.
Note, a version starts with the -
, as separator, and a slot starts with the :
, as separator.
All I can think of is:
if [[ "$1" =~ ^${CATEGORY_PACKAGE}-${VERSION}:${SLOT}$ ]] ; then
# use "${BASH_REMATCH[n]}" here to capture groups contents
else
if [[ "$1" =~ ^${CATEGORY_PACKAGE}:${SLOT}$ ]] ; then
# use "${BASH_REMATCH[n]}" here to capture groups contents
else
if [[ "$1" =~ ^${CATEGORY_PACKAGE}-${VERSION}$ ]] || [[ "$1" =~ ^${CATEGORY_PACKAGE}$ ]] ; then
# use "${BASH_REMATCH[n]}" here to capture groups contents
fi
fi
fi
Is this a full solution?
Is there a better version?
Is there a POSIX solution based on options, like <category-name>(<slot option>|<version option>|<version:slot> option)
?
EDIT:
I think bash can handle optional groups in one expression, but I fail to change ([^[:space:]:]+)
to handle a hyphen
. How can hyphen
be included as does not seem to work neither as the first, nor the last in the range?
foo-bar-2022
, is2022
a version or part of the name of the package?foo-category/foo-bar-2022
, but to work without categories would be a plus. As a rule, versions are separated by the name by a-
.[^-[:space:]:]
or[^[:space:]:-]
work to match any character except whitespace, colon and hyphen but since your package names can apparently contain-
s, it's probably not an option.