正则表达式查找所有 UUID,其中每组中的字母按字母顺序排序

正则表达式查找所有 UUID,其中每组中的字母按字母顺序排序

UUID 由 5 组组成,由 '-' 分隔,由十六进制字符组成。我正在尝试创建一个正则表达式来查找所有 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,按字母顺序排列。

第二个 UUID 中每个组中的字母未按字母顺序排序:efc 和 accef

一个组也只能有一次相同的字母,因此第三个 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

它对我来说适用于 GNU grep3.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](perl 扩展)
  • (?1)调用与第一组相同的正则表达式以避免重复(perl 扩展)。

相关内容