我认为更好的方法是使用括号将您感兴趣的模式括起来。
In your case, I would use the following regular expression:
string.gsub(/(?<=[a-z])_([a-z]+)/) {|s| "#{s[1].upcase}#{s[2..-1]}"}
This regexp can be read in two parts, the first ask for string that starts with valid char and the second is followed by "_" and a sequence of valid chars.
Inside the block code, you can use Regexp.last_match and will return the MatchData where you can access each pattern inside the parentheses, ex:
string.gsub(/(?<=[a-z])_([a-z]+)/) do |s|
p Regexp.last_match.to_a # this will print all sub-patterns found
"#{s[1].upcase}#{s[2..-1]}" # return formatted string
end
As you mentioned, you are not interesting in patterns inside quotes. I would use a regular expression inside other. The first one to remove quoted string and second one to search for patterns:
string.scan(/(\"[^\"]+\"|([^\"]+))/) do |s|
next s[0] unless s[1] # skip quoted data
# replace snake case to camel case
s[1].gsub(/(?<=[a-z])_([a-z]+)/) {|s| "#{s[1].upcase}#{s[2..-1]}"}
end