我有这段代码:
(1..40).map(&:to_s).grep(/[2-3][0-9]/)
因此,当我输入[2-3][0-9]
时,它将打印范围内的所有数字(介于20和39之间)。如何在不定义范围的情况下执行此操作(即,在这种情况下,它是" 1..40")因此它适用于我在括号中键入的任何正则表达式?
与
类似的代码(1..40).map(&:to_s).grep(/[2-3][0-9]/)
没有(1..40).map
部分就可以使用。
答案 0 :(得分:2)
好的,这太糟糕了,你真的可能真的不想这样做,你只是觉得你这样做。但是,FWIW:
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
例如
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)
例如
irb(main):122:0> this_is_awful("a[b-e][f-g]")
=> ["abf", "abg", "acf", "acg", "adf", "adg", "aef", "aeg"]
编辑2:修复了以数组
开头的错误答案 1 :(得分:0)
你要做的是暴力强迫。它效率低,速度慢。这只是一种错误的方法,所以忘掉RegEx。
您将需要一个真正的算法。所以我为你做了一个......
我将假设你的输入将只包括号码:1
,并这样定义的范围:[2-6]
或两者的任何组合,导致像的字符串:1[2-3][5-7]9
想象一下,这是一个包含两种元素的可能数字的向量(数组):
我们转换输入1[2-3][5-7]9
的示例应如下所示:
[ [1,1], [2,3], [5,7], [9,9] ]
此数组中的第一个元素([1,1]
)是第一个数字的范围,第二个数字的第二个数字([2,3]
),依此类推。
将它变成这样的东西相对容易。这是一个包含两个元素的数组数组 - 每个范围的起始和结束编号。
所以你现在需要做的是输出每个可能的值。这可以通过对每个数字进行简单的递归来完成,为每个数字的每个数字开始一个新的分支。
以下是实现递归的示例:
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的所有功能,但速度很快,会产生数字。
P.S。哇..这花了我一个小时来创建和调试。希望它有所帮助。