首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Ruby on Rails中使用正则表达式定义范围

在Ruby on Rails中使用正则表达式定义范围
EN

Stack Overflow用户
提问于 2014-03-10 23:03:56
回答 2查看 198关注 0票数 0

我有这样的代码:

代码语言:javascript
复制
(1..40).map(&:to_s).grep(/[2-3][0-9]/)

因此,当我键入[2-3][0-9]时,它将打印范围内的所有数字(介于20和39之间)。如果不定义范围(即本例中的范围是"1..40"),如何才能使其适用于我在括号中键入的任何正则表达式?

所以代码类似于

代码语言:javascript
复制
(1..40).map(&:to_s).grep(/[2-3][0-9]/) 

这将在没有(1..40).map部件的情况下工作。

EN

回答 2

Stack Overflow用户

发布于 2014-03-11 01:29:27

好吧,这太可怕了,你可能真的不想这样做,你只是认为你想这样做。但是,FWIW:

代码语言:javascript
复制
def this_is_awful(string)
  results = []
  string.split("|").each do |section|
    #example section is "5[0-3][2-4]"
    section_digits = []
    section.split(/[\[\]]+/).select{|s| s.size > 0}.each do |range_string|
      range_digits = range_string.split("-").select{|s| s.size > 0}
      arrays = (range_digits[0]..range_digits[-1]).to_a
      section_digits << arrays if arrays.size > 0
    end
    #now we need every combination of these
    section_digits[0].product(*section_digits[1..-1]).each do |combination|
      results << combination unless results.include?(combination)
    end
  end
  #at this point, results will be like [[5, 0, 2], [5, 0, 3], [5, 0, 4], etc].  Sort these and convert them to digits via strings
  results.sort.collect{|arr| arr.join}
end

例如

代码语言:javascript
复制
irb(main):075:0> this_is_awful("5[2-3]")
=> [52, 53]
irb(main):076:0> this_is_awful("5[2-3][3-9]")
=> [523, 524, 525, 526, 527, 528, 529, 533, 534, 535, 536, 537, 538, 539]
irb(main):077:0> this_is_awful("5[2-3][3-9]|10[1-7][3-8]")
=> [523, 524, 525, 526, 527, 528, 529, 533, 534, 535, 536, 537, 538, 539, 1013, 1014, 1015, 1016, 1017, 1018, 1023, 1024, 1025, 1026, 1027, 1028, 1033, 1034, 1035, 1036, 1037, 1038, 1043, 1044, 1045, 1046, 1047, 1048, 1053, 1054, 1055, 1056, 1057, 1058, 1063, 1064, 1065, 1066, 1067, 1068, 1073, 1074, 1075, 1076, 1077, 1078]

顺便说一句,这个问题与Ruby on Rails无关。

编辑:我只是对它进行了编辑,以便更通用地使用任何枚举对象(例如,它也可以使用字母)。现在,您可以获得返回的字符串,但如果您希望使用.collect(&:to_i),则可以将它们转换为整数

例如

代码语言:javascript
复制
irb(main):122:0>     this_is_awful("a[b-e][f-g]")
=> ["abf", "abg", "acf", "acg", "adf", "adg", "aef", "aeg"]

编辑2:修复了以数组开始时的错误

票数 2
EN

Stack Overflow用户

发布于 2014-03-11 02:02:05

你正在尝试做的是蛮横的强迫。这是低效和缓慢的。这只是一种错误的方法,所以忘记RegEx吧。

你将需要一个真实的算法。所以我给你做了一个...

我假设您的输入将只包括numbers:1和像这样定义的范围:[2-6]或两者的任意组合,从而产生一个类似:1[2-3][5-7]9的字符串。

假设这是一个包含两种类型元素的可能数字的向量(数组):

  • 可能的数字范围。
  • fixed digit (这是一个数字到同一数字的范围)

我们转换的输入1[2-3][5-7]9的示例应该如下所示:

代码语言:javascript
复制
[ [1,1], [2,3], [5,7], [9,9] ]

此数组中的第一个元素([1,1])是第一个数字的范围,第二个([2,3])是第二个数字的范围,依此类推。

把它变成像这样的东西相对容易。这是一个数组数组,包含两个元素--每个范围的开始和结束编号。

因此,您现在需要做的是输出每个可能的值。这可以通过对每个数字进行简单的递归来完成,为它的每个可能值启动一个新的分支。

下面是一个实现该递归示例:

代码语言:javascript
复制
def recursion(array, number = '')
    return if array.empty? # Don't bother if the digits array is empty

    # iterate over each possible value of the current pair
    (array[0][0]..array[0][1]).each do |i|
        if array.length <= 1 # If the digits array is empty (contains only the current range)
            # then an entire number would have been generated, so print it
            puts number + i.to_s
        else
            # Start a new branch passing the array (without the current element)
            # and the generated number until this moment
            recursion(array[1..-1], number + i.to_s)
        end
    end
end

array = [ [1,1], [2,3], [5,7], [9,9] ]

recursion(array)

按照这种方法,您可以尽可能地使函数变得复杂。

我提供了如何计算数字本身的例程,但没有提供如何创建array的例程,我希望您可以处理。

这很难实现,当然也不包含RegEx的所有功能,但速度很快,生成的数字会像地狱一样。

附言:哇..这花了我一个小时的时间来创建和调试。希望能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22303791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档