Jes
Jes

Reputation: 343

Replacement with regular expression and capture

The method below is supposed to transform "snake_case" to "CamelCase".

def zebulansNightmare(string)
  string.gsub(/_(.)/){$1.upcase}
end

With string "camel_case", I expect gsub(/_(.)/) to match c after the _. I understood that $1 is the first matched letter: the capital letter. But it works like it's substituting _ with the capital letter. Why has the _ disappeared?

Upvotes: 2

Views: 68

Answers (2)

Cary Swoveland
Cary Swoveland

Reputation: 110665

def zebulans_nightmare(string)
  string.gsub(/\B_[a-z0-9]/) { |s| s[1].upcase }
end

zebulans_nightmare("case_of_snakes")
  #=> "caseOfSnakes" 
zebulans_nightmare("case_of_3_snakes")
  #=> "caseOf3Snakes" 
zebulans_nightmare("_case_of_3_snakes")
  #=> "_caseOf3Snakes" 

\B matches non-word boundaries.

Upvotes: 1

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626690

You are right that $1 is the captured value, however, the gsub matches the letter with _ before it, and the whole match gets replaced. You need to reinsert _ to the result:

"camel_case".gsub(/_(.)/){"_#{$1.upcase}"}

See the IDEONE demo

BTW, if you only plan to match _ followed with a letter (so as not to waste time and resources on trying to turn non-letters to upper case), you can use the following regex:

/_(\p{Ll})/

Where \p{Ll} is any lowercase Unicode letter.

Upvotes: 2

Related Questions