Photo By Mr. Christopher Thomas
Creative Commons Attribution-ShareALike 2.0 Generic License
Beneath the
Surface
Embracing ...
^4[0-9]{12}(?:[0-9]{3})?$
Source: regular-expressions.info
We fear what we
do not understand
Regular
Expressions
+
Ruby
Photo By Shayan
Creative Commons Attribution-ShareALike 2.0 Generic License
Regex Matching in Ruby
Ruby
Methods
Onigmo
Onigmo
Oniguruma
Onigmo
Fork
Onigmo
Reads
Regex
Onigmo
Reads
Regex
Abstract
Syntax
Tree
Parses
Into
Onigmo
Reads
Regex
Abstract
Syntax
Tree
Series of
Instructions
Parses
Into
Compiles
Into
Finite State Machines
Photo By Felipe Skroski
Creative Commons Attribution Generic 2.0
A Finite State Machine
Shows How
Something Works
Annie the Dog
In the
House
Out of
House
Annie the Dog
In the
House
Out of
House
Annie the Dog
Door
In the
House
Out of
House
Annie the Dog
Door
Door
Finite
State
Machine
Finite
State
Machine
Finite
State
Machine
Multiple States
/force/
re = /force/
string = “Use the force”
re.match(string)
f o r c e
/force/
“Use the force”
Path
Doesn’t
Match
f o r c e
/force/
“Use the force”
Still
Doesn’t
Match
f o r c e
/force/
“Use the force”
Path
Matches!
(Fast Forward)
f o r c e
/force/
“Use the force”
f o r c e
/force/
“Use the force”
f o r c e
/force/
“Use the force”
f o r c e
/force/
“Use the force”
f o r c e
/force/
“Use the force”
We Have
A Match!
re = /force/
string = “Use the force”
re.match(string)
=> #<MatchData “force”>
Alternation
Photo By Shayan
Creative Commons Attribution Generic 2.0
/Y(olk|oda)/
Pipe
re = /Y(olk|oda)/
string = “Yoda”
re.match(string)
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”
Y o
o
l k
d a
/Y(olk|oda)/
Which To
Choose?
“Yoda”
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”Saves To
Backtrack
Stack
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”Uh Oh,
No Match
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”Backtracks
To Here
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”
Y o
o
l k
d a
/Y(olk|oda)/
“Yoda”
We Have
A Match!
re = /Y(olk|oda)/
string = “Yoda”
re.match(string)
=> #<MatchData “Yoda”>
Photo By Fancy Horse
Creative Commons Attribution Generic 2.0
Quantifiers
/No+/
Plus
Quantifier
re = /No+/
string = “Noooo”
re.match(string)
N o
o
/No+/
“Noooo”
N o
o
/No+/
“Noooo”
N o
o
/No+/
“Noooo”
Return
Match?
Or Keep
Looping?
N o
o
/No+/
“Noooo”
Greedy
Quantifier
Keeps
Looping
Greedy quantifiers match
as much as possible
Greedy quantifiers use
maximum effort for
maximum return
N o
o
/No+/
“Noooo”
N o
o
/No+/
“Noooo”
N o
o
/No+/
“Noooo”
We Have
A Match!
re = /No+/
string = “Noooo”
re.match(string)
=> #<MatchData “Noooo”>
Lazy Quantifiers
Lazy quantifiers match
as little as possible
Lazy quantifiers use
minimum effort for
minimum return
/No+?/
Makes
Quantifier
Lazy
re = /No+?/
string = “Noooo”
re.match(string)
N o
o
“Noooo”
/No+?/
N o
o
“Noooo”
/No+?/
N o
o
“Noooo”
/No+?/
Return
Match?
Or Keep
Looping?
N o
o
“Noooo”
/No+?/
We Have
A Match!
re = /No+?/
string = “Noooo”
re.match(string)
=> #<MatchData “No”>
Greedy quantifiers are
greedy but reasonable
/.*moon/
Star
Quantifier
re = /.*moon/
string = “That’s no moon”
re.match(string)
. m o o n
.
/.*moon/
“That’s no moon”
. m o o n
.
“That’s no moon”
/.*moon/
. m o o n
.
“That’s no moon”
Loops
/.*moon/
. m o o n
. Which To
Match?
(Fast Forward)
“That’s no moon”
/.*moon/
. m o o n
.
“That’s no moon”
Keeps
Looping
/.*moon/
. m o o n
.
“That’s no moon”
Keeps
Looping
/.*moon/
. m o o n
.
“That’s no moon”
Keeps
Looping
/.*moon/
. m o o n
“That’s no moon”
No More
Characters?
.
/.*moon/
. m o o n
“That’s no moon”
Backtrack or Fail?
.
/.*moon/
. m o o n
“That’s no moon”
Backtracks
.
/.*moon/
. m o o n
“That’s no moon”
Backtracks
.
/.*moon/
. m o o n
“That’s no moon”
Backtracks
.
/.*moon/
. m o o n
“That’s no moon”
Backtracks
Huzzah!
.
/.*moon/
. m o o n
“That’s no moon”
.
/.*moon/
. m o o n
“That’s no moon”
.
/.*moon/
. m o o n
“That’s no moon”
.
/.*moon/
. m o o n
“That’s no moon”
. We Have
A Match!
/.*moon/
re = /.*moon/
string = “That’s no moon”
re.match(string)
=> #<MatchData “That’s
no moon”>
Backtracking = Slow
/No+w+/
re = /No+w+/
string = “Noooo”
re.match(string)
N o
o
“Noooo”
/No+w+/
w
w
N o
o
“Noooo”
/No+w+/
w
w
N o
o
“Noooo”
/No+w+/
w
wLoops
N o
o
“Noooo”
/No+w+/
w
wLoops
N o
o
“Noooo”
/No+w+/
w
wLoops
N o
o
“Noooo”
/No+w+/
w
w
Uh Oh
N o
o
“Noooo”
/No+w+/
w
w
Uh Oh
Backtrack or Fail?
N o
o
“Noooo”
/No+w+/
w
wBacktracks
N o
o
“Noooo”
/No+w+/
w
wBacktracks
N o
o
“Noooo”
/No+w+/
w
wBacktracks
N o
o
“Noooo”
/No+w+/
w
w
Match FAILS
Possessive Quantifers
Possessive quantifiers
do not backtrack
Makes
Quantifier
Possessive
/No++w+/
N o
o
“Noooo”
w
w
/No++w+/
N o
o
“Noooo”
w
w
/No++w+/
N o
o
“Noooo”
w
wLoops
/No++w+/
N o
o
“Noooo”
w
wLoops
/No++w+/
N o
o
“Noooo”
w
wLoops
/No++w+/
N o
o
“Noooo”
w
w
/No++w+/
N o
o
“Noooo”
w
wLoops
Uh Oh
Backtrack or Fail?
/No++w+/
N o
o
“Noooo”
w
w
Match FAILS
/No++w+/
Possessive quantifiers
fail faster by
controlling backtracking
Tying It All Together
Photo By Keith Ramos
Creative Commons Attribution 2.0 Generic
snake_case to CamelCase
Find first letter of string and
capitalize it
snake_case to CamelCase
Find first letter of string and
capitalize it
Find any character that follows
an underscore and capitalize it
snake_case to...
Find first letter of string and
capitalize it
Find any character that follows an
underscore and capitalize it
Remove unders...
Find first letter of string and
capitalize it
snake_case to CamelCase
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
.upcase_chars(ʺ″methodʺ″)
result.should == ʺ″Methodʺ″
c...
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
.upcase_chars(ʺ″methodʺ″)
result.should == ʺ″Methodʺ″
c...
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
.upcase_chars(ʺ″methodʺ″)
result.should == ʺ″Methodʺ″
c...
/ /^
Anchors
Match To
Beginning Of
String
/ / w^
Matches Any
Word
Character
case_converter.rb
def upcase_chars(string)
end
re = / /w^
string.gsub(re){|char| char.upcase}
case_converter.rb
def upcase_chars(string)
end
re = / /w^
string.gsub(re){|char| char.upcase}
case_converter.rb
def upcase_chars(string)
end
re = / /w^
string.gsub(re){|char| char.upcase}
Spec Passes!
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
result.should == ʺ″_Methodʺ″
case_converter_spec.rb
.up...
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
result.should == ʺ″_Methodʺ″
case_converter_spec.rb
.up...
it ʺ″capitalizes the first letterʺ″ do
end
result = @case_converter
result.should == ʺ″_Methodʺ″
case_converter_spec.rb
.up...
Expected: ʺ″_Methodʺ″
Got: ʺ″_methodʺ″
Spec Failure:
Problem:
Matches Letters
AND Underscores
 w^/ /
/ /[a-z]^
Matches
Only
Lowercase
Letters
/ /[a-z]^[^a-z]
Matches
everything
BUT
lowercase
letters
/ /[a-z]^[^a-z]?
Makes
Character
Class
Optional
case_converter.rb
def upcase_chars(string)
end
re =
string.gsub(re){|char| char.upcase}
/ /[a-z]^[^a-z]?
case_converter.rb
def upcase_chars(string)
end
string.gsub(re){|char| char.upcase}
Spec Passes!
re = / /[a-z]^[^a-z]?
Find any character that follows an
underscore and capitalize it
snake_case to CamelCase
it ʺ″capitalizes letters after an underscoreʺ″ do
end
result = @case_converter
result.should == ʺ″Some_Methodʺ″
case_conve...
it ʺ″capitalizes letters after an underscoreʺ″ do
end
result = @case_converter
result.should == ʺ″Some_Methodʺ″
case_conve...
/ /[a-z]^[^a-z]?
Pipe For
Alternation
| [a-z]/ /[a-z]^[^a-z]?
Look Behind
(?<=_)| [a-z]/ /[a-z]^[^a-z]?
case_converter.rb
def upcase_chars(string)
end
re =
string.gsub(re){|char| char.upcase}
| [a-z](?<=_)/ /[a-z]^[^a-z]?
case_converter.rb
def upcase_chars(string)
end
re =
string.gsub(re){|char| char.upcase}
| [a-z](?<=_)/ /[a-z]^[^a-z]?
Spec...
Remove underscores
snake_case to CamelCase
it ʺ″removes underscoresʺ″ do
end
result = @case_converter
result.should == ʺ″somemethodʺ″
case_converter_spec.rb
.rmv_und...
it ʺ″removes underscoresʺ″ do
end
result = @case_converter
result.should == ʺ″somemethodʺ″
case_converter_spec.rb
.rmv_und...
it ʺ″removes underscoresʺ″ do
end
result = @case_converter
result.should == ʺ″somemethodʺ″
case_converter_spec.rb
.rmv_und...
Matches
An
Underscore
/ /_
case_converter.rb
def rmv_underscores(string)
end
re =
string.gsub(re, “”)
/ /_
case_converter.rb
def rmv_underscores(string)
end
string.gsub(re, “”)
re = / /_
case_converter.rb
def rmv_underscores(string)
end
string.gsub(re, “”)
Spec Passes!
re = / /_
Combine results of two methods
snake_case to CamelCase
it ʺ″converts snake_case to CamelCaseʺ″ do
end
result = @case_converter
result.should == ʺ″SomeMethodʺ″
case_converter_spe...
it ʺ″converts snake_case to CamelCaseʺ″ do
end
result = @case_converter
result.should == ʺ″SomeMethodʺ″
case_converter_spe...
it ʺ″converts snake_case to CamelCaseʺ″ do
end
result = @case_converter
result.should == ʺ″SomeMethodʺ″
case_converter_spe...
case_converter.rb
def snake_to_camel(string)
end
upcase_chars(string)
case_converter.rb
def snake_to_camel(string)
end
upcase_chars(string)rmv_underscores( )
case_converter.rb
def snake_to_camel(string)
end
upcase_chars(string)rmv_underscores( )
Spec Passes!
Code is available here:
https://github.com/nellshamrell/
snake_to_camel_case
Conclusion
Photo By Steve Jurvetson
Creative Commons Attribution Generic 2.0
Develop regular expressions
in small pieces
If you write code, you can
write regular expressions
Move beyond the fear
Photo By Leonardo Pallotta
Creative Commons Attribution Generic 2.0
Nell Shamrell
Software Development Engineer
Blue Box I...
Beneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in Ruby
Beneath the Surface: Regular Expressions in Ruby
Upcoming SlideShare
Loading in …5
×

Beneath the Surface: Regular Expressions in Ruby

1,233 views

Published on

Many of us approach regular expressions with a certain fear and trepidation, using them only when absolutely necessary. We can get by when we need to use them, but we hesitate to dive any deeper into their cryptic world. Ruby has so much more to offer us. This talk showcases the incredible power of Ruby and the Oniguruma regex library Ruby runs on. It takes you on a journey beneath the surface, exploring the beauty, elegance, and power of regular expressions. You will discover the flexible, dynamic, and eloquent ways to harness this beauty and power in your own code.

0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,233
On SlideShare
0
From Embeds
0
Number of Embeds
74
Actions
Shares
0
Downloads
18
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide

Beneath the Surface: Regular Expressions in Ruby

  1. 1. Photo By Mr. Christopher Thomas Creative Commons Attribution-ShareALike 2.0 Generic License Beneath the Surface Embracing the True Power of Regular Expressions in Ruby @nellshamrell
  2. 2. ^4[0-9]{12}(?:[0-9]{3})?$ Source: regular-expressions.info
  3. 3. We fear what we do not understand
  4. 4. Regular Expressions + Ruby Photo By Shayan Creative Commons Attribution-ShareALike 2.0 Generic License
  5. 5. Regex Matching in Ruby Ruby Methods Onigmo
  6. 6. Onigmo
  7. 7. Oniguruma Onigmo Fork
  8. 8. Onigmo Reads Regex
  9. 9. Onigmo Reads Regex Abstract Syntax Tree Parses Into
  10. 10. Onigmo Reads Regex Abstract Syntax Tree Series of Instructions Parses Into Compiles Into
  11. 11. Finite State Machines Photo By Felipe Skroski Creative Commons Attribution Generic 2.0
  12. 12. A Finite State Machine Shows How Something Works
  13. 13. Annie the Dog
  14. 14. In the House Out of House Annie the Dog
  15. 15. In the House Out of House Annie the Dog Door
  16. 16. In the House Out of House Annie the Dog Door Door
  17. 17. Finite State Machine
  18. 18. Finite State Machine
  19. 19. Finite State Machine
  20. 20. Multiple States
  21. 21. /force/
  22. 22. re = /force/ string = “Use the force” re.match(string)
  23. 23. f o r c e /force/ “Use the force” Path Doesn’t Match
  24. 24. f o r c e /force/ “Use the force” Still Doesn’t Match
  25. 25. f o r c e /force/ “Use the force” Path Matches! (Fast Forward)
  26. 26. f o r c e /force/ “Use the force”
  27. 27. f o r c e /force/ “Use the force”
  28. 28. f o r c e /force/ “Use the force”
  29. 29. f o r c e /force/ “Use the force”
  30. 30. f o r c e /force/ “Use the force” We Have A Match!
  31. 31. re = /force/ string = “Use the force” re.match(string) => #<MatchData “force”>
  32. 32. Alternation Photo By Shayan Creative Commons Attribution Generic 2.0
  33. 33. /Y(olk|oda)/ Pipe
  34. 34. re = /Y(olk|oda)/ string = “Yoda” re.match(string)
  35. 35. Y o o l k d a /Y(olk|oda)/ “Yoda”
  36. 36. Y o o l k d a /Y(olk|oda)/ Which To Choose? “Yoda”
  37. 37. Y o o l k d a /Y(olk|oda)/ “Yoda”Saves To Backtrack Stack
  38. 38. Y o o l k d a /Y(olk|oda)/ “Yoda”Uh Oh, No Match
  39. 39. Y o o l k d a /Y(olk|oda)/ “Yoda”Backtracks To Here
  40. 40. Y o o l k d a /Y(olk|oda)/ “Yoda”
  41. 41. Y o o l k d a /Y(olk|oda)/ “Yoda”
  42. 42. Y o o l k d a /Y(olk|oda)/ “Yoda” We Have A Match!
  43. 43. re = /Y(olk|oda)/ string = “Yoda” re.match(string) => #<MatchData “Yoda”>
  44. 44. Photo By Fancy Horse Creative Commons Attribution Generic 2.0 Quantifiers
  45. 45. /No+/ Plus Quantifier
  46. 46. re = /No+/ string = “Noooo” re.match(string)
  47. 47. N o o /No+/ “Noooo”
  48. 48. N o o /No+/ “Noooo”
  49. 49. N o o /No+/ “Noooo” Return Match? Or Keep Looping?
  50. 50. N o o /No+/ “Noooo” Greedy Quantifier Keeps Looping
  51. 51. Greedy quantifiers match as much as possible
  52. 52. Greedy quantifiers use maximum effort for maximum return
  53. 53. N o o /No+/ “Noooo”
  54. 54. N o o /No+/ “Noooo”
  55. 55. N o o /No+/ “Noooo” We Have A Match!
  56. 56. re = /No+/ string = “Noooo” re.match(string) => #<MatchData “Noooo”>
  57. 57. Lazy Quantifiers
  58. 58. Lazy quantifiers match as little as possible
  59. 59. Lazy quantifiers use minimum effort for minimum return
  60. 60. /No+?/ Makes Quantifier Lazy
  61. 61. re = /No+?/ string = “Noooo” re.match(string)
  62. 62. N o o “Noooo” /No+?/
  63. 63. N o o “Noooo” /No+?/
  64. 64. N o o “Noooo” /No+?/ Return Match? Or Keep Looping?
  65. 65. N o o “Noooo” /No+?/ We Have A Match!
  66. 66. re = /No+?/ string = “Noooo” re.match(string) => #<MatchData “No”>
  67. 67. Greedy quantifiers are greedy but reasonable
  68. 68. /.*moon/ Star Quantifier
  69. 69. re = /.*moon/ string = “That’s no moon” re.match(string)
  70. 70. . m o o n . /.*moon/ “That’s no moon”
  71. 71. . m o o n . “That’s no moon” /.*moon/
  72. 72. . m o o n . “That’s no moon” Loops /.*moon/
  73. 73. . m o o n . Which To Match? (Fast Forward) “That’s no moon” /.*moon/
  74. 74. . m o o n . “That’s no moon” Keeps Looping /.*moon/
  75. 75. . m o o n . “That’s no moon” Keeps Looping /.*moon/
  76. 76. . m o o n . “That’s no moon” Keeps Looping /.*moon/
  77. 77. . m o o n “That’s no moon” No More Characters? . /.*moon/
  78. 78. . m o o n “That’s no moon” Backtrack or Fail? . /.*moon/
  79. 79. . m o o n “That’s no moon” Backtracks . /.*moon/
  80. 80. . m o o n “That’s no moon” Backtracks . /.*moon/
  81. 81. . m o o n “That’s no moon” Backtracks . /.*moon/
  82. 82. . m o o n “That’s no moon” Backtracks Huzzah! . /.*moon/
  83. 83. . m o o n “That’s no moon” . /.*moon/
  84. 84. . m o o n “That’s no moon” . /.*moon/
  85. 85. . m o o n “That’s no moon” . /.*moon/
  86. 86. . m o o n “That’s no moon” . We Have A Match! /.*moon/
  87. 87. re = /.*moon/ string = “That’s no moon” re.match(string) => #<MatchData “That’s no moon”>
  88. 88. Backtracking = Slow
  89. 89. /No+w+/
  90. 90. re = /No+w+/ string = “Noooo” re.match(string)
  91. 91. N o o “Noooo” /No+w+/ w w
  92. 92. N o o “Noooo” /No+w+/ w w
  93. 93. N o o “Noooo” /No+w+/ w wLoops
  94. 94. N o o “Noooo” /No+w+/ w wLoops
  95. 95. N o o “Noooo” /No+w+/ w wLoops
  96. 96. N o o “Noooo” /No+w+/ w w Uh Oh
  97. 97. N o o “Noooo” /No+w+/ w w Uh Oh Backtrack or Fail?
  98. 98. N o o “Noooo” /No+w+/ w wBacktracks
  99. 99. N o o “Noooo” /No+w+/ w wBacktracks
  100. 100. N o o “Noooo” /No+w+/ w wBacktracks
  101. 101. N o o “Noooo” /No+w+/ w w Match FAILS
  102. 102. Possessive Quantifers
  103. 103. Possessive quantifiers do not backtrack
  104. 104. Makes Quantifier Possessive /No++w+/
  105. 105. N o o “Noooo” w w /No++w+/
  106. 106. N o o “Noooo” w w /No++w+/
  107. 107. N o o “Noooo” w wLoops /No++w+/
  108. 108. N o o “Noooo” w wLoops /No++w+/
  109. 109. N o o “Noooo” w wLoops /No++w+/
  110. 110. N o o “Noooo” w w /No++w+/
  111. 111. N o o “Noooo” w wLoops Uh Oh Backtrack or Fail? /No++w+/
  112. 112. N o o “Noooo” w w Match FAILS /No++w+/
  113. 113. Possessive quantifiers fail faster by controlling backtracking
  114. 114. Tying It All Together Photo By Keith Ramos Creative Commons Attribution 2.0 Generic
  115. 115. snake_case to CamelCase
  116. 116. Find first letter of string and capitalize it snake_case to CamelCase
  117. 117. Find first letter of string and capitalize it Find any character that follows an underscore and capitalize it snake_case to CamelCase
  118. 118. Find first letter of string and capitalize it Find any character that follows an underscore and capitalize it Remove underscores snake_case to CamelCase
  119. 119. Find first letter of string and capitalize it snake_case to CamelCase
  120. 120. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter .upcase_chars(ʺ″methodʺ″) result.should == ʺ″Methodʺ″ case_converter_spec.rb before(:each) do end @case_converter = CaseConverter.new
  121. 121. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter .upcase_chars(ʺ″methodʺ″) result.should == ʺ″Methodʺ″ case_converter_spec.rb before(:each) do end @case_converter = CaseConverter.new
  122. 122. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter .upcase_chars(ʺ″methodʺ″) result.should == ʺ″Methodʺ″ case_converter_spec.rb before(:each) do end @case_converter = CaseConverter.new
  123. 123. / /^ Anchors Match To Beginning Of String
  124. 124. / / w^ Matches Any Word Character
  125. 125. case_converter.rb def upcase_chars(string) end re = / /w^ string.gsub(re){|char| char.upcase}
  126. 126. case_converter.rb def upcase_chars(string) end re = / /w^ string.gsub(re){|char| char.upcase}
  127. 127. case_converter.rb def upcase_chars(string) end re = / /w^ string.gsub(re){|char| char.upcase} Spec Passes!
  128. 128. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter result.should == ʺ″_Methodʺ″ case_converter_spec.rb .upcase_chars(ʺ″_methodʺ″)
  129. 129. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter result.should == ʺ″_Methodʺ″ case_converter_spec.rb .upcase_chars(ʺ″_methodʺ″)
  130. 130. it ʺ″capitalizes the first letterʺ″ do end result = @case_converter result.should == ʺ″_Methodʺ″ case_converter_spec.rb .upcase_chars(ʺ″_methodʺ″) Spec Fails!
  131. 131. Expected: ʺ″_Methodʺ″ Got: ʺ″_methodʺ″ Spec Failure:
  132. 132. Problem: Matches Letters AND Underscores w^/ /
  133. 133. / /[a-z]^ Matches Only Lowercase Letters
  134. 134. / /[a-z]^[^a-z] Matches everything BUT lowercase letters
  135. 135. / /[a-z]^[^a-z]? Makes Character Class Optional
  136. 136. case_converter.rb def upcase_chars(string) end re = string.gsub(re){|char| char.upcase} / /[a-z]^[^a-z]?
  137. 137. case_converter.rb def upcase_chars(string) end string.gsub(re){|char| char.upcase} Spec Passes! re = / /[a-z]^[^a-z]?
  138. 138. Find any character that follows an underscore and capitalize it snake_case to CamelCase
  139. 139. it ʺ″capitalizes letters after an underscoreʺ″ do end result = @case_converter result.should == ʺ″Some_Methodʺ″ case_converter_spec.rb .upcase_chars(ʺ″some_methodʺ″)
  140. 140. it ʺ″capitalizes letters after an underscoreʺ″ do end result = @case_converter result.should == ʺ″Some_Methodʺ″ case_converter_spec.rb .upcase_chars(ʺ″some_methodʺ″)
  141. 141. / /[a-z]^[^a-z]?
  142. 142. Pipe For Alternation | [a-z]/ /[a-z]^[^a-z]?
  143. 143. Look Behind (?<=_)| [a-z]/ /[a-z]^[^a-z]?
  144. 144. case_converter.rb def upcase_chars(string) end re = string.gsub(re){|char| char.upcase} | [a-z](?<=_)/ /[a-z]^[^a-z]?
  145. 145. case_converter.rb def upcase_chars(string) end re = string.gsub(re){|char| char.upcase} | [a-z](?<=_)/ /[a-z]^[^a-z]? Spec Passes!
  146. 146. Remove underscores snake_case to CamelCase
  147. 147. it ʺ″removes underscoresʺ″ do end result = @case_converter result.should == ʺ″somemethodʺ″ case_converter_spec.rb .rmv_underscores(ʺ″some_methodʺ″)
  148. 148. it ʺ″removes underscoresʺ″ do end result = @case_converter result.should == ʺ″somemethodʺ″ case_converter_spec.rb .rmv_underscores(ʺ″some_methodʺ″)
  149. 149. it ʺ″removes underscoresʺ″ do end result = @case_converter result.should == ʺ″somemethodʺ″ case_converter_spec.rb .rmv_underscores(ʺ″some_methodʺ″)
  150. 150. Matches An Underscore / /_
  151. 151. case_converter.rb def rmv_underscores(string) end re = string.gsub(re, “”) / /_
  152. 152. case_converter.rb def rmv_underscores(string) end string.gsub(re, “”) re = / /_
  153. 153. case_converter.rb def rmv_underscores(string) end string.gsub(re, “”) Spec Passes! re = / /_
  154. 154. Combine results of two methods snake_case to CamelCase
  155. 155. it ʺ″converts snake_case to CamelCaseʺ″ do end result = @case_converter result.should == ʺ″SomeMethodʺ″ case_converter_spec.rb .snake_to_camel(ʺ″some_methodʺ″)
  156. 156. it ʺ″converts snake_case to CamelCaseʺ″ do end result = @case_converter result.should == ʺ″SomeMethodʺ″ case_converter_spec.rb .snake_to_camel(ʺ″some_methodʺ″)
  157. 157. it ʺ″converts snake_case to CamelCaseʺ″ do end result = @case_converter result.should == ʺ″SomeMethodʺ″ case_converter_spec.rb .snake_to_camel(ʺ″some_methodʺ″)
  158. 158. case_converter.rb def snake_to_camel(string) end upcase_chars(string)
  159. 159. case_converter.rb def snake_to_camel(string) end upcase_chars(string)rmv_underscores( )
  160. 160. case_converter.rb def snake_to_camel(string) end upcase_chars(string)rmv_underscores( ) Spec Passes!
  161. 161. Code is available here: https://github.com/nellshamrell/ snake_to_camel_case
  162. 162. Conclusion Photo By Steve Jurvetson Creative Commons Attribution Generic 2.0
  163. 163. Develop regular expressions in small pieces
  164. 164. If you write code, you can write regular expressions
  165. 165. Move beyond the fear
  166. 166. Photo By Leonardo Pallotta Creative Commons Attribution Generic 2.0 Nell Shamrell Software Development Engineer Blue Box Inc @nellshamrell https://gist.github.com/ nellshamrell/6031738 Resources:

×