Ruby Regex:多次捕获相同的捕获组

3hvapo4f  于 2022-12-18  发布在  Ruby
关注(0)|答案(1)|浏览(151)

我已经在我们的身份验证系统中获得了这些字符串,并且我正在尝试开发正确的REGEX来从它们中捕获特定的信息。

STRING = CR*reduced*downsized*U*reduced*D*own_only

现在,我需要能够提取第一个捕获组中的大写字母(如CRUD),加上紧接着的由星号包含的“属性”(例如,downsized)。

(C)\*?([a-z_]+)?\*?    --> Capture Group 1: "C", Capture Group2: empty
(U)\*?([a-z_]+)?\*?    --> Capture Group 1: "U", Capture Group2: 'reduced'
(C)\*?([a-z_]+)?\*?    --> Capture Group 1: "D", Capture Group2: 'own_only'

对于R,我需要返回这两个属性,因此Capture Group2应该是“reduced”,Capture Group3应该是“downsized”。

(R)\*?([a-z_]+)?\*?    --> Capture Group 1: "R", Capture Group2: 'reduced'


关于Regex有什么建议吗?

nimxete2

nimxete21#

由于这是一个涉及repeated capturing groups的场景,因此可以使用多步骤解决方案,如

text = 'CR*reduced*downsized*U*reduced*D*own_only'
rx = /([CRUD])((?:\*[a-z_]+(?:\*[a-z_]+)*(?:\*|$))?)/
matches = text.scan(rx)
p matches.map { |x| [x[0], x[1].split("*").reject(&:empty?)]};
# => [["C", []], ["R", ["reduced", "downsized"]], ["U", ["reduced"]], ["D", ["own_only"]]]

请参见Ruby demoregex demo

  • 详细信息 *:
  • ([CRUD])-组1:四个字母中的一个
  • ((?:\*[a-z_]+(?:\*[a-z_]+)*(?:\*|$))?)-第2组:一个可选的序列
  • \*-一个*字符
  • [a-z_]+-一个或多个ASCII小写字母或下划线
  • (?:\*[a-z_]+)*-零个或多个*序列以及一个或多个ASCII小写字母或下划线
  • (?:\*|$)-*或行尾(使用\z匹配整个字符串的行尾)。

使用.map { |x| [x[0], x[1].split("*").reject(&:empty?)]},您可以使用*拆分第二个组值并删除空项。

相关问题