Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Ruby 2.0 regexps and other goodies
Search
taw
June 15, 2013
Programming
93
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Ruby 2.0 regexps and other goodies
From BarCamp Berkshire 2
taw
June 15, 2013
Other Decks in Programming
See All in Programming
コーディング自動化の次へ。人の介入をゼロにするファクトリーとサポートAIによる実践
timakin
5
3.6k
SalesForceを内製化!? ~ HR事業を支える顧客管理基盤のインフラを大公開 ~
oku053
0
180
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
130
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
Jetpack Compose Mechanisms
skydoves
3
820
C#の現在地 進化の歴史と、AI時代の.NET Everywhere
neuecc
5
5.2k
3回つくってわかった、 定期実行ジョブ基盤の本質情報
takai
0
480
月間100万人のサービス刷新で、 技術選定をHonoに振り切った話
yutobara
8
6.6k
JIS keyboard support in Omarchy
lef237
0
120
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
作って学ぶSpring BootのAuto Configuration / JJUG Night Seminar 2026-10-19
rshindo
0
150
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
1.1k
Featured
See All Featured
WCS-LA-2024
lcolladotor
0
890
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
2
410
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
570
Building an army of robots
kneath
307
47k
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
Are puppies a ranking factor?
jonoalderson
2
4.1k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3.1k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
310
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
600
DBのスキルで生き残る技術 - AI時代におけるテーブル設計の勘所
soudai
PRO
68
58k
Art, The Web, and Tiny UX
lynnandtonic
304
22k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Transcript
Ruby 2.0 regexps (and other goodies)
Never use ^ and $ unless you absolutely know what
you're doing. Only ever use \A and \z Public Service Announcement
puts "SELECT * FROM users WHERE user_id='#{id}'" if id =~
/^\d+$/ id = "'; DROP TABLE users;--\n1" ^ and $ are start and end of line. \A and \z are start and end of string. You want \A and \z 99% of time. ^ and $ do not do what you think
Character classes ASCII: • /[a-zA-Z0-9_]+/ • /\w+/ Unicode: • /[[:alnum:]]+/
(letters/numbers) • /[[:alnum:]_]+/ (mix them freely) • /\p{L}+/ (just letters) • /\p{Letter}+/ (just letters) • /[\p{L}\p{N}_]+/ • /[\p{Letter}\p{Number}_]+/
Non-capturing groups /([+-]?\d+(\.\d+)?)/ - hygiene fail /([+-]?\d+(?:\.\d+)?)/ Retrospectively, non-capturing ()
should have been default, but it's too late to change.
Named groups rx = /\A(?<name>.*)\.(?<ext>.*)\z/ "kittens.jpg".match(rx) rx["name"] #=> kittens "kittens.jpg"
=~ rx $~["name"] => "kittens" $~ is last match $1 is only alias for $~[1] etc.
String#[] Works, but verbose: "kitty.jpg" =~ /.\(\.*)\z/ ? $1 :
nil Nicer syntax: "kitty.jpg"[/\.(\.*)\z/] # => ".jpg" "kitty.jpg"[/\.(.*)\z/, 1] # => "jpg" "kitty.jpg"[/\.\K.*\z/] # => "jpg"
Irregular Expressions "((1(2)3)(45))" =~ /\A(?<expr>(?:\d+|\ (\g<expr>\))+)\z/ /\A (?<expr> (?:\d+ |
\( \g<expr> \) )+ )\z /x
String#scan "Kittens are cute!".scan(/\w+/) => ["Kittens", "are", "cute"] "x +
42".scan /(\d+)|(\p{L}+)|([+\- *\/])/ => [ [nil, "x", nil], [nil, nil, "+"], ["42", nil, nil] ]
Just one more step "x + 42".scan /(?<num>\d+) | (?<var>\p{L}+)
| (?<op> [+\-*\/])/x "x+42".scan(rx){ if $~["num"] ... end }
Regexp class escapes for you Regexp.quote(".jpg") => "\\.jpg" Regexp.new("kittens.jpg") =>
/kittens\.jpg/ Regexp.union("cute","kittens",".jpg") => /cute|kittens|\.jpg/
Perl regexps still a lot better Ruby is catching up
slowly Less regexp culture in Ruby world People often scared of regexps
%i %i[symbols everywhere] => [:symbols, :everywhere] %I[symbols in ruby#{ RUBY_VERSION
}] => [:symbols, :in, :"ruby2.0.0"]
%W %w[ruby is awesome] => ["ruby", "is", "awesome"] %W[mongod --shardsvr
--port #{port} --fork -- dbpath #{data_dir} --logappend --logpath # {logpath} --directoryperdb] %W is not just %Q[].split
%r /(?<num>\d+)|(?<var>\p{L}+)|(?<op>[+\- *\/])/ %r! (?<num>\d+) | (?<var>\p{L}+) | (?<op>[+\-*/]) !x
You can even use %r[ [] [] [] ] if balanced
__dir__ No more File.dirname(__FILE__)
#to_h OpenStruct.new( foo: 123, bar: 456 ).to_h => {:foo=>123, :bar=>456}
Not supported by most hash-like things yet (like MatchData with named groups)
Keyword arguments, before 2.0 def hello(opts={}) place = opts[:place] ||
"world" puts "Hello, #{place}" end hello # => Hello, world hello :place => "Barcamp" # => Hello, Barcamp hello place: "Barcamp" # since 1.9 # => Hello, Barcamp
Keyword arguments in 2.0 def hello(place: "world") puts "Hello, #{place}"
end hello place: "Barcamp" Mostly syntactic sugar. New style - arity 0 Old style - arity -1
Module#prepend class HelloWorld prepend Memoizer.new(:hello) def hello(who) puts "Calculating #{who}
greeting" "Hello, #{who}" end end Simpler than include + alias_method_chain
Just like Python's @annotations class Memoizer < Module def initialize(*methods)
methods.each{|m| self.send(:define_method, m){|*args| @cache ||= {} @cache[[m, *args]] ||= super(*args) } } end end
More goodies • Enumerator#lazy • Refinements (???) • Performance vs
1.9? Reports differ • Mostly backwards compatible • Everything UTF-8 by default now
What still isn't great • Perl still has better regexps
• Pathname#to_str removed :-( • More classes need #to_h • Performance still not awesome
Bonus slide - parsing XML XmlParsingRegexp = %r[ \A(?<doc>\s* (?<node>
( <\s*\w+ (?<attrs> (?:\s+ \w+\s*=\s*("[^"]*"| '[^']*'))* ) \s*> ( \g<node> | [^&<] | &\#\d+; | &\#x\h+; )* </\s*\w+\s*> ) | ( <\s*\w+ \g<attrs> \s*/> ) ) \s*)\z]x
Questions?