Here's a non-regex solution that makes use of Ruby's little-used flip-flop operator:
str = "foo,baz(some,other,stuff),hello,goodbye"
str.split(',').chunk { |s| s.include?('(') .. s.include?(')') ? true : false }.
flat_map { |tf, a| tf ? a.join(' ') : a }
#=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"]
The steps:
arr = str.split(',')
#=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"]
enum = arr.chunk { |s| s.include?('(') .. s.include?(')') ? true : false }
#=> #<Enumerator: #<Enumerator::Generator:0x007fdf9d01d2e8>:each>
Aside: the flip-flop
operator must be within an if
statement, so this cannot be simplified to:
enum = arr.chunk { |s| s.include?('(') .. s.include?(')') }
We can convert this enumerator to an array to see the values it will pass on to Enumerable#flat_map:
enum.to_a
#=> [[false, ["foo"]], [true, ["baz(some", "other", "stuff)"]],
# [false, ["hello", "goodbye"]]]
Lastly:
enum.flat_map { |tf, a| tf ? a.join(' ') : a }
#=> ["foo", "baz(some", "other", "stuff)", "hello", "goodbye"]