我有这样的代码:
(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部件的情况下工作。
发布于 2014-03-11 01:29:27
好吧,这太可怕了,你可能真的不想这样做,你只是认为你想这样做。但是,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:修复了以数组开始时的错误
发布于 2014-03-11 02:02:05
你正在尝试做的是蛮横的强迫。这是低效和缓慢的。这只是一种错误的方法,所以忘记RegEx吧。
你将需要一个真实的算法。所以我给你做了一个...
我假设您的输入将只包括numbers: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的所有功能,但速度很快,生成的数字会像地狱一样。
附言:哇..这花了我一个小时的时间来创建和调试。希望能有所帮助。
https://stackoverflow.com/questions/22303791
复制相似问题