Skip to content

Instantly share code, notes, and snippets.

@2called-chaos
Last active August 29, 2015 14:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 2called-chaos/3710922bfd25c71c5b52 to your computer and use it in GitHub Desktop.
Save 2called-chaos/3710922bfd25c71c5b52 to your computer and use it in GitHub Desktop.
Expand range like strings into lists/arrays with ruby, example at the bottom
#---
# Copyright (c) 2013, Sven Pachnit
# Published under the MIT license
#
# I wrote this in 15 minutes, I have no idea about performance.
# CPAN's String::Range::Expand is the only thing I was able to
# find and Perl is not good for my Ruby eyes ;)
#---
# result of me being lazy :)
require "active_support/core_ext"
# Expands ranges in strings into a list.
# Will propably break if your string contains [ or ] which are not defining a range.
class StringExpandRange
def self.expand str
new(str).expand
end
def initialize str
@str = str.dup
@list = [""]
@chunks = @str.split(/(\[[^\]]+\])/i).reject(&:blank?)
end
def append str
@list.each{|s| s << str }
end
def add str
@list << str
end
def multiply_with list
@list.replace(@list.product(list).map(&:join))
end
def expand
@chunks.each do |chunk|
if chunk.start_with?("[") && chunk.end_with?("]")
# expression, expand it and multiply with list
multiply_with expand_expression(chunk[1..-2])
else
# normal part, append it to all list entries
append(chunk)
end
end
@list.sort
end
def expand_expression expression
reg = [[],[]]
expression.split(",").map(&:strip).reject(&:blank?).each do |part|
# negate?
index = 0
if part.start_with?("^")
index = 1
part = part[1..-1]
end
# range or element
if m = part.match(/([^-]+)\-([^-]+)/i)
reg[index].concat (m[1]..m[2]).to_a
else
reg[index] << part
end
end
reg[0] - reg[1]
end
end
# Usage
r = StringExpandRange.expand "v[14,15]x[12,^33,32-34][a-c]"
puts r.inspect
# v14x12a
# v14x12b
# v14x12c
# v14x32a
# v14x32b
# v14x32c
# v14x34a
# v14x34b
# v14x34c
# v15x12a
# v15x12b
# v15x12c
# v15x32a
# v15x32b
# v15x32c
# v15x34a
# v15x34b
# v15x34c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment