Skip to content

Instantly share code, notes, and snippets.

@icy
Last active March 6, 2019 14:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save icy/2cd2e8183b0357507465 to your computer and use it in GitHub Desktop.
Save icy/2cd2e8183b0357507465 to your computer and use it in GitHub Desktop.
Bash-liked Curly Brace Expansion in ruby

System-call method

Use Bash to expand the brace. If you don't like this, you may look at more professional way at https://gist.github.com/ewoodh2o/3829405 This method invokes a system call to ask Bash to expand.

FIXME: This is not secure!!!

class String
  # x{a-b}y => x{a-b}y
  def expand
    %x[for u in #{self.gsub(" ", '')}; do echo $u; done].split("\n")
  end
  
  # x{a-b}y => xa-by
  def expand2
    self.expand \
    .map do |st|
      st.gsub(/[{}]/, '')
    end
  end
end

Recursive method

FIXME: This version is too noisy. E.g, {a{,b}, c} is expanded to a, c, ab, c.

UTF8_3OK = "✓✓✓"

def icy_brace_expand(st)
  counts = 0
  st.scan(/{([^{}]+)}/) do |_|
    counts += 1
  end

  if counts > 6; then
    STDERR.puts "__icy_brace_expand: Too many groups (count: #{counts})"
    return [st]
  end

  # Important: At most one!!!
  expander = nil
  st.sub!(/{([^{}]+)}/) do |_|
    expander = $1
    UTF8_3OK
  end

  if expander
    rets = expander.split(",", -1).map do |br|
      st.gsub(UTF8_3OK, br)
    end
  else
    return [st]
  end

  rets.map{|p| icy_brace_expand(p)}.flatten
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment