The Geppy String: Regex vs Iteration We'll say that a lowercase 'g' in a string is "happy" if there is another 'g' immediately to its left or right. Return true if all the g's in the given string are happy.

gHappy("xxggxx") → true
gHappy("xxgxx") → false
gHappy("xxggyygxx") → false



I have written two functions to solve this problem, but I have some concerns:


Of the one with Regex, I don't like all the special cases.
Of the one with iteration, I don't like the weird helper method.


Both pass a fair number of tests and work correctly. Which one is better?

regex_geppy.rb

def geppy(string)
  return true if ! string.include?('g')
  return false if [0, 1].include?(string.length)
  return false if string.length == 2 &amp;&amp; string != 'gg'
  return (not string.match("[^g]g[^g]"))
end


array_geppy.rb

def non_wrap_get(array, index)
  index &lt; 0 ? nil : array[index]
end

def geppy(string)
  string
    .chars
    .each_with_index
    .all? { |curr, i| 
      curr == 'g' ? 
        non_wrap_get(string, i - 1) == 'g'  || non_wrap_get(string, i + 1) == 'g' 
        : true
    }
end


geppy_tests

geppy("xxggxx") #=&gt; true
geppy("xxgxx") #=&gt; false
geppy("xxggyygxx") #=&gt; false
geppy("g") #=&gt; false
geppy("ag") #=&gt; false
geppy("gg") #=&gt; true
geppy("") #=&gt; true
geppy("ab") #=&gt; true
geppy("aaaa") #=&gt; true
geppy('g'*1000) #=&gt; true
Regular expressions are the right tool to use for this kind of test.  However, if you are going to use a regular expression to find lonely g characters, then you should use negative lookbehind and lookahead assertions instead of the negated character class [^g].

def geppy(str)
  !/(?&lt;!g)g(?!g)/.match(str)
end