Simplify series of string manipulations in Ruby I have a series of string manipulation, I realize this with the following code. I want it to be more elegant and readable such as str.sub_heading().sub_codeblock()..., how could I rewrite my code?

def sub_heading(str)
  str.gsub!(/^(#+)\w+/) {|m|  m.gsub("#", "=")}
  str.gsub!(/^(=+)(.+)/, '\1 \2 \1')
end

def sub_codeblock(str)
  str.gsub!(/```(.+\n)((.|\n)+)```/,  '{{{#!text_pygments \1\2}}}')
end

def sub_inlinecode(str)
  str.gsub!(/`(.+)`/, '{{{\1}}}')
end

def sub_bold(str)
  str.gsub!(/([^\w]|^)\*\*\w[\w\s\d\-_'"]*\*\*([^\w]|$)/) {|m|  m.gsub("**", "'''")}
end

def sub_italic(str)
  str.gsub!(/([^*]|^)\*\w[\w\s\d\-_'"]*\*([^*]|$)/) {|m|  m.gsub("*", "''")}
end

def sub_link(str)
  str.gsub!(/\[\[(.+)\|(.+)\]\]/, '[[\2|\1]]')
end

sub_heading(inputdata)
sub_codeblock(inputdata)
sub_inlinecode(inputdata)
sub_bold(inputdata)
sub_italic(inputdata)
sub_link(inputdata)
You may collect the replacements in a Hash and call them on after the other.

replacements = { 
  /1/ =&gt; ' one ',
  /2/ =&gt; ' two ',
  /([34])/ =&gt; ' (\1 is three or four) ',
}

test = '123'
replacements.each{|regex, repl|
  test.gsub!(regex, repl)
}
p test


The gsub-version with blocks need a little trick:

replacements = { 
  /1/ =&gt; ' one ',
  /2/ =&gt; ' two ',
  /3/ =&gt; Proc.new{|m| m*2},
}

test = '123'
replacements.each{|regex, repl|
  if repl.is_a?(Proc)
    test.gsub!(regex){|m| repl.call(m)}
  else
  test.gsub!(regex, repl)
  end
}
p test


In your case you may define your replacements with:

Replacements = {
  # sub_heading 
  /^(#+)\w+/                                    =&gt; Proc.new{|m|  m.gsub("#", "=")},
  /^(=+)(.+)/                                   =&gt; '\1 \2 \1',
  # sub_codeblock
  /```(.+\n)((.|\n)+)```/                       =&gt; '{{{#!text_pygments \1\2}}}',
  # sub_inlinecode 
   /`(.+)`/                                     =&gt; '{{{\1}}}',
  # sub_bold
  /([^\w]|^)\*\*\w[\w\s\d\-_'"]*\*\*([^\w]|$)/  =&gt; Proc.new{|m|  m.gsub("**", "'''")},
  # sub_italic
  /([^*]|^)\*\w[\w\s\d\-_'"]*\*([^*]|$)/        =&gt; Proc.new{|m|  m.gsub("*", "''")},
  # sub_link
  /\[\[(.+)\|(.+)\]\]/                          =&gt; '[[\2|\1]]',
}

def my_replace(inputstring)
  Replacements.each{|regex, repl|
    if repl.is_a?(Proc)
      inputstring.gsub!(regex){|m| repl.call(m)}
    else
    inputstring.gsub!(regex, repl)
    end
  }
end

my_replace(inputdata)