Bash posix正規表現オプショングループ

Bash posix正規表現オプショングループ

カテゴリ/名前バージョン形式の文字列で、コンポーネントという名前の一部のGentooパッケージを一致させる試みの複雑さのため、次の結論に達しました。

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

期待どおりに文字列を分割します<category/package-name-12345.25b_rc10-r7

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

これで、バージョンが欠落している可能性がある文字列を一致させて分割する必要がありますcategory/package-name

それでは、上記のバージョン部分をオプションにする方法はありませんか?

上記では、この部分は次のとおりです。

-(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?)?

私はそれを次のように変更しようとしました。

(-(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+)))?))?

バージョンのない文字列に対しては機能しますが、オプションのグループのため、上記のように少し完全な文字列と一致しないようです。

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:

編集する:スロットマシン

オプション部品2個はいかがですか?

上記に加えて、スロットは一致する必要があります。スロットは次のように一致します。

:(([[:digit:]]+)(\.([[:digit:]]+))*)?

今、カテゴリ/名前の部分があります。

([<>]?=?)(([^\/]+)\/)?([^[:space:]]+)

次のいずれかのバージョンがあります。 -(([[:digit:]]+)(\.([[:digit:]]+))*)([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?

スロット :(([[:digit:]]+)(\.([[:digit:]]+))*)?

または、バージョンとスロットの両方を適切な順序で選択します。

-バージョンは区切り文字で始まり、スロットは:区切り文字で始まります。

私が考えることができるものは:

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

これは完全な解決策ですか?より良いバージョンがありますか?たとえば、オプションベースのPOSIXソリューションはありますか<category-name>(<slot option>|<version option>|<version:slot> option)

編集する:

([^[:space:]:]+)bashが式でオプションのグループを処理できると思いましたが、それを処理するように変更することはできませんhyphenhyphen範囲の最初または最後にはできないようですが、どのように含めるべきですか?

ベストアンサー1

IMOでは、可能なすべてのケースを単一の正規表現にまとめるよりも、この場合は複数の正規表現を使用する方が良いです。

base_package_name_regex='^([<>]?=?)(([^/]+)/)?([^[:space:]]+)'
version_regex='(([[:digit:]]+)?(\.([[:digit:]]+))*([a-z])?(_(alpha|beta|pre|rc|p)([[:digit:]]*))*(-(r([[:digit:]]+))?)?)?$ '
if [[ "$1" =~ $base_package_name_regex-$version_regex ]] || # package with version number
    [[ "$1" =~ $base_package_name_regex ]]  #  package without version number

then
    # use "${BASH_REMATCH[n]}" here to capture groups contents
fi

また、POSIX EREでは一致\/は指定されず、[^\/]バックスラッシュやスラッシュを除くすべての文字と一致します。私はその偽のバックスラッシュを削除しました。

おすすめ記事