正则表达式:仅捕获 Ruby 中的匹配替代项

问题描述 投票:0回答:1

我对此感到非常惊讶: 我正在构建一个简单的密码生成器,它使用用户创建的模式。该模式包含字母 a-f,代表 6 个字符组:

Password Generator

因此,如果用户输入 ababcd,他/她会得到类似

abce1!
的内容 模式 Abababababaccd 会生成类似
Robuxejiqu23#
的内容。 由于 Abababababccd 看起来很难读,我想提供通过重复缩写的可能性: Abababababaccd 可以写成
Ab(ab){5}ccd
甚至
Ab(ab){5}c{2}d
(这可能很愚蠢,但为了完整性)。 如果想要使用 a 组或 b 组中的角色,则 [ab] 就会发挥作用。

我“构建”了一个合适的正则表达式,它捕获以下组合中的重复:

  1. a{3}
    这样的单个字符重复会变成
    aaa
  2. 小组重复
    (ab){2}
    会变成
    abab
  3. XOR 组重复
    [ab]{2}
    变为
    ab
    aa
    ba
  4. 2和3的组合:
    (a[bc]d){n}

我到目前为止构建的正则表达式找到了上述所有情况:

/(?:(\[[abcdef]+\])|\(([\[\]abcdef]+)\)|([abcdef]))\{(\d+)\}/i

我的工作 Ruby 代码看起来像这样,但它想找到一个更优雅的解决方案:

# class
REPETITION = /(?:(\[[abcdef]+\])|\(([\[\]abcdef]+)\)|([abcdef]))\{(\d+)\}/i
GROUPS = /\[([abcdefxyz]+)\]/i;

# method generate
pattern = params[:pattern]
group = {
  'A' => params[:group_a].upcase,
  'a' => params[:group_a],
  'B' => params[:group_b].upcase,
  'b' => params[:group_b],
  'C' => params[:group_c].upcase,
  'c' => params[:group_c],
  'D' => params[:group_d].upcase,
  'd' => params[:group_d],
  'E' => params[:group_e].upcase,
  'e' => params[:group_e],
  'F' => params[:group_f].upcase,
  'f' => params[:group_f]
}

# Evaluate repetitions: ...{n}
if pattern =~ REPETITION
  pattern.gsub!(REPETITION) do
    match = $1 != nil ? $1 : $2 != nil ? $2 : $3
    count=$4.to_i
    expanded=""
    count.times do
      expanded+=match
    end
    expanded
  end
end

# Evaluate character groups [...]
if pattern =~ GROUPS
  pattern.gsub!(GROUPS) do
    $1[rand($1.length)]
  end
end

# Evaluate the final pattern (repetitions and []-groups processed)
password=""
pattern.each_char do |c|
  password+=group[c][rand(group[c].length)]
end
@password=password;

我的想法是找到所有出现的情况,并用扩展的重复替换重复,以便

Ab(ab){5}ccd
变成
Ababababababccd
,然后我进行处理。

我的假设是

.gsub
单独处理每个事件,并且我可以用合适的模式和计数替换每个匹配。如果 gsub 尝试一次替换所有这些,那将是错误的方法。

对我来说, (?:a|b|c){count} 中的哪个组匹配并不重要,但匹配项应返回为 $1,计数应返回为 $2。

上述正则表达式导致匹配 $1、$2、$3 和 $4。 4 美元始终是我的重复次数。但接下来我必须找出哪个 $1 .. $3 不是

nil
并用它来扩展。我可以选择“便宜”的案例,然后if通过案例,但我想要一个优雅的解决方案。

在 regex101 中,我让它可以与

(?|
一起使用,但 Ruby 不理解

我希望我清楚我想要什么!?

在 Typescript 和 C# 中我让它可以工作,现在我希望它能在 Ruby 中工作......:-)

regex ruby
1个回答
0
投票

我已经编辑了这个问题,以便我当前的(不优雅的)代码可供任何人使用。如果有人有好的建议,请随时发表评论或回答。

© www.soinside.com 2019 - 2024. All rights reserved.