如何在Ruby中解析包含通配符和字符类的字符串?

如何在Ruby中解析包含通配符和字符类的字符串?,ruby,parsing,Ruby,Parsing,我想编写一个脚本,其中包含一个可能如下所示的参数: abc(ag)de* a、 b,c是文字字符 ag表示“a”或“g” *指任何一个字母或数字 我希望脚本创建一个包含输入可以表示的所有可能字符串的数组。目的是检查它们是否有可用的域名 输入也可以是类似于abcagdemnlop的东西,其中有不止一个字符类 似乎第一个任务是将其拆分为一个或多个数组,因此第一个示例是 [ ['a'], ['b'], ['c'], ['a', 'g'], ['d'], ['e'], [

我想编写一个脚本,其中包含一个可能如下所示的参数:

abc(ag)de*
a、 b,c是文字字符

ag表示“a”或“g”

*指任何一个字母或数字

我希望脚本创建一个包含输入可以表示的所有可能字符串的数组。目的是检查它们是否有可用的域名

输入也可以是类似于abcagdemnlop的东西,其中有不止一个字符类

似乎第一个任务是将其拆分为一个或多个数组,因此第一个示例是

[
  ['a'],
  ['b'],
  ['c'],
  ['a', 'g'],
  ['d'],
  ['e'],
  [
    'a', 'b', 'c', 'd', 'e', 'f', 'g',
    # etc...
  ]
]
这就是我被卡住的地方。我不知道怎么把它分成那样的碎片


有什么建议吗?

如果你的*只表示一个字符,那么我想这至少是可以解决的。如果它意味着任何字符的零个或多个,那么您的解决方案空间就好像是在无限边界上,因此很难作为实际的具体值返回

我想我应该通过某种方式来解决这个问题,分解变量部分,计算出每个变量支持多少个变量,然后在概念上以嵌套的方式循环所有变量,为最内层循环的每次迭代形成一个输出字符串

对于abcagde*的示例字符串,这可以归结为Python-ish伪代码,my Ruby不公开使用:

results = []
for x in "ag":
  for y in "abcdefghijklmnopqrstuvwxyz":
    results.append("abc%sde%s" % (x, y))

最后一行字符串中的%s是一个格式说明符,s只是表示字符串,并将导致字符串后面%运算符右侧元组中的相应值在该位置进行插值。

这是一个非常简洁的解决方案。它并没有针对性能进行优化,这会对您提供的模式造成一些限制,例如,过多的通配符可能不是最好的主意

这是密码

input1 = "abc(ag)de*"
input2 = "abc(ag)de(mnlop)"

class Array
  def append_suffixes!(suffixes)
    self.replace suffixes.map { |a| self.map { |p| p + a }}.flatten
  end
end

def generate_combinations(pattern)
  combinations = [""]
  pattern.scan(/\(([^)]+)\)|(\*)|(\w+)/) do |group,wildcard,other|
    new_suffixes = case
      when group    : group.split('')
      when wildcard : [*'a'..'z']
      when other    : other
      else raise "Unknown match!"
    end
    combinations.append_suffixes! new_suffixes
  end
  combinations
end

p generate_combinations(input1)
p generate_combinations(input2)
p generate_combinations("**").size
运行上述代码的输出经过轻微编辑:

["abcadea", "abcgdea", "abcadeb", "abcgdeb", "abcadec", 
 "abcgdec", "abcaded", "abcgded", "abcadee", "abcgdee", 
 "abcadef", "abcgdef", "abcadeg", "abcgdeg", "abcadeh", 
 "abcgdeh", "abcadei", "abcgdei", "abcadej", "abcgdej", 
 "abcadek", "abcgdek", "abcadel", "abcgdel", "abcadem", 
 "abcgdem", "abcaden", "abcgden", "abcadeo", "abcgdeo", 
 "abcadep", "abcgdep", "abcadeq", "abcgdeq", "abcader", 
 "abcgder", "abcades", "abcgdes", "abcadet", "abcgdet", 
 "abcadeu", "abcgdeu", "abcadev", "abcgdev", "abcadew", 
 "abcgdew", "abcadex", "abcgdex", "abcadey", "abcgdey", 
 "abcadez", "abcgdez"]

["abcadem", "abcgdem", "abcaden", "abcgden", "abcadel", 
 "abcgdel", "abcadeo", "abcgdeo", "abcadep", "abcgdep"]

676 # The number of two letter words i.e. 26*26

如果您对上述代码有任何疑问,请随时询问。

您的主要要求是获取一个regexp并生成它匹配的所有字符串


是的。请看左侧的解决方案。

标题a和a之间缺少一个单词。我不确定正确的单词应该是string?,所以你应该修正它;你可能会发现我在网站上发布的C答案很有帮助。在您的情况下,数组将是您已经为第一个stask生成的数组。基本的递归算法应该相对容易转化为问题的解决方案。但我不认识Ruby,所以我把它留给你或其他人。星星只代表一个角色。