各グループの文字がアルファベット順にソートされたすべてのUUIDを見つける正規表現

各グループの文字がアルファベット順にソートされたすべてのUUIDを見つける正規表現

UUIDは、「-」で区切られた5つのグループで構成され、16進文字で構成されています。各グループの文字がアルファベット順に並べられたすべてのUUIDを見つける正規表現を作成しようとしています。

入力する:

9a578cf1-bc9f-49ad-8294-a61b736088c5
64efc3d9-448a-4902-a6c6-61849ac6c7ef
75b39f65-b614-427a-af62-922534bee490

出力:

9a578cf1-bc9f-49ad-8294-a61b736088c5

各文字セットは acf bcf ad abc で、アルファベット順にソートされます。

2番目のUUIDの各グループの文字はアルファベット順ではありません:efcとaccef

また、グループには同じ文字が1回しかない場合があるため、3番目のUUIDの「bee」もアルファベット順とは見なされません。

次のgrepコマンドを試しました。

grep -P "^[0-9]*a?[0-9]*b?[0-9]*c?[0-9]*d?[0-9]*e?[0-9]*f?[0-9]*(-[0-9]*a?[0-9]*b?[0-9]*c?[0-9]*d?[0-9]*e?[0-9]*f?[0-9]*){4}$" file.txt

しかし、これは逆追跡エラーを引き起こします。

答え1

grep遅いですが、GNU 3.7および3.8バージョンで動作します。

他のgrep実装および/またはバージョン、または他の正規表現エンジンに切り替えると便利です。コードにはPerlに関する内容はありません。たとえば、-Eここで代わりに使用できます(-Pegrepアルゴリズムは、逆追跡の必要性を防止します。ここ)。

(?>...)いずれにせよ、バックトレースは不要で非生産的であるため、(perl拡張機能)を使用してバックトレースを完全に無効にすることをお勧めします。

grep -Px '(?>(\d*a?\d*b?\d*c?\d*d?\d*e?\d*f?\d*)(?:-(?1)){4})'

いくつかの追加のショートカットがあります:

  • -x 代わりに使用し^$固定してください。
  • \d代わりに[0-9](パール拡張)
  • (?1)重複を避けるために、最初のセットと同じ正規表現を呼び出します(perl拡張)。

関連情報