s Perl 5 Regular Expression Perl 6 Regex

  • Slides: 66
Download presentation
s/ Perl 5 Regular Expression / Perl 6 Regex and Rules /mixes; 竹迫 良範

s/ Perl 5 Regular Expression / Perl 6 Regex and Rules /mixes; 竹迫 良範

自己紹介 n My Name is n 竹迫良範 n Yoshinori TAKESAKO n Perlとの関係 n 1997

自己紹介 n My Name is n 竹迫良範 n Yoshinori TAKESAKO n Perlとの関係 n 1997 n Perlと出会う n 2003 n mod_perl C 10 K Problem ※モヒカン族では ありません http: //namazu. org/~takesako/ http: //labs. cybozu. co. jp/blog/takesako/ n 2005 n ppencode n Joined Cybozu. Labs, Inc. 4

My first computer

My first computer

6

6

C, X 11(Xlib), UNIX Network Programming n Require n X Window System, Version 11

C, X 11(Xlib), UNIX Network Programming n Require n X Window System, Version 11 Release 5 ~ n OS n Linux 2. 0. 17 n Sun. OS Release 4. 1. 3 n Solaris 2. 1 n IRIX Release 5. 3 n Machines n Sun SPARC station LX n Sun SPARC station 5 n Gateway 2000 Hand. Book i 486 やっぱりゲーム作ってました(汗) 9

11

11

My Programming History @Home @school @office Java BASIC x 86 ? C Perl Portability

My Programming History @Home @school @office Java BASIC x 86 ? C Perl Portability FM TOWNS 限定された独自 アーキテクチャ UNIX Network X 11 Windows HP-UX Linux 12

Perl を選択 13

Perl を選択 13

現在に至る n Shibuya Perl Mongers リーダー交代式 n Basokiya 2006 Cup いまここ 14

現在に至る n Shibuya Perl Mongers リーダー交代式 n Basokiya 2006 Cup いまここ 14

Perl 6 Today yesterday 15

Perl 6 Today yesterday 15

16

16

17

17

audreyt++ 18

audreyt++ 18

Today’s Perl 6 Talks n 09: 30 - Dan “Fred” Kogai n ふつうの Perl

Today’s Perl 6 Talks n 09: 30 - Dan “Fred” Kogai n ふつうの Perl 6 入門 n An Ordinary Perl 6 Guide n 13: 15 - Yoshinori Takesako n s/ Perl 5 Regular Expression / Perl 6 Regex and Rules /mixes; n 正規表現にフォーカスした Perl 6 入門 19

正規表現 Perl 5 Perl 6 20

正規表現 Perl 5 Perl 6 20

Agenda 21

Agenda 21

繰り返し *+? と選択 | Perl 6 Perl 5 /x*/ /y+/ /z? / /foo|bar/ #

繰り返し *+? と選択 | Perl 6 Perl 5 /x*/ /y+/ /z? / /foo|bar/ # # xが0個以上繰り返し yが1個以上繰り返し zが0個以上1個以下 fooまたはbar $_ = "aaa bbb ccc foo moo zoo"; if (/aaax*/) { print "okn" } if (/b+/) { print "okn" } if (/cccc? /) { print "okn" } if (/foo|bar|baz/) { print "okn" } /x*/ /y+/ /z? / /foo|bar/ $_ if if # # == == Perl 5 5 = "aaa bbb ccc foo moo zoo"; /aaax*/ { say "ok" } /b+/ { say "ok" } /cccc? / { say "ok" } /foo|bar|baz/ { say "ok" } 26

文字列のパターンマッチ m// Perl 6 Perl 5 /pattern/ m{pattern} qr/pattern/ m/pattern/ m{pattern} rx/pattern/ $_ =

文字列のパターンマッチ m// Perl 6 Perl 5 /pattern/ m{pattern} qr/pattern/ m/pattern/ m{pattern} rx/pattern/ $_ = "This is a pen. "; if /This/ { say "ok" } if m/pen/ { say "ok" } if m{pen} { say "ok" } unless /not match/ { say "ok" } if ($_ ~~ rx/pen/) { say "ok" } if (/This/) { print "okn" } if (m/pen/) { print "okn" } if (m{pen}) { print "okn" } unless (/not match/) { print "okn" } if ($_ =~ qr/pen/) { print "okn" } または regex{pattern} ※ただし、Pugs 6. 2. 13 では「m##」や「m()」の記号を使用するとエラーになります 28

スマートマッチ演算子 ~~ Perl 5 $str =~ /pattern/ $str !~ /pattern/ Perl 6 $str ~~

スマートマッチ演算子 ~~ Perl 5 $str =~ /pattern/ $str !~ /pattern/ Perl 6 $str ~~ /pattern/ $str !~~ /pattern/ ~~ $str /pattern/ !~~ $str my $str = "This is a pen. "; if ($str =~ /This/) { print "okn" } if $str ~~ /This/ { say "ok" } if ($str =~ m/pen/) { print "okn" } if $str ~~ m/pen/ { say "ok" } ## (m/pen/ =~ $str) とは書けない if m/pen/ ~~ $str { say "ok" } if ($str !~ /not match/) { print "okn" } if $str !~~ /not match/ { say "ok" } unless ($str ~~ /not match/) { print "okn" } unless $str ~~ /not match/ { say "ok" } 29

文字列の置換 s/// Perl 5 Perl 6 s/pattern/replace/ s{pattern}{replace} s{pattern} = 'replace' s{pattern}{replace} my $str

文字列の置換 s/// Perl 5 Perl 6 s/pattern/replace/ s{pattern}{replace} s{pattern} = 'replace' s{pattern}{replace} my $str = "This is a pen. "; if ($str =~ s/pen/book/) { if ($str eq "This is a book. ") { print "okn" } } if ($str =~ s{book}{notebook}) { if ($str eq "This is a notebook. ") { print "okn" } } if $str ~~ s/pen/book/ { if $str eq "This is a book. " { say "ok" } } if $str ~~ s{book} = 'notebook' { if $str eq "This is a notebook. " { say "ok" } } ※Rubyでは文字列の置換を「s[/pattern/] = 'replace'」と書くことができる。 30

複数行モード/m 修飾子の廃止 Perl 5 /^ pattern $/m Perl 6 /^^ pattern $$/ 正規表現の修飾子/mで「^」と「$」のマッチ規則が変わる my

複数行モード/m 修飾子の廃止 Perl 5 /^ pattern $/m Perl 6 /^^ pattern $$/ 正規表現の修飾子/mで「^」と「$」のマッチ規則が変わる my $lines = "aaanbbbncccn"; if ($lines =~ /^b/m) { print "okn" } if ($lines =~ /bb$/m) { print "okn" } if ($lines =~ /^bbb$/m) {     print "okn"; } my if if if $lines = "aaanbbbncccn"; $lines ~~ /^^b/ { say "ok" } $lines ~~ /bb$$/ { say "ok" } $lines ~~ /^^bbb$$/ { say "ok" ; } 32

文字列の先頭「A」末尾「z」の廃止 Perl 5 /A pattern z/ Perl 6 /^ pattern $/ 複数行モード/m に影響しないアンカー記号「A」「z」 my

文字列の先頭「A」末尾「z」の廃止 Perl 5 /A pattern z/ Perl 6 /^ pattern $/ 複数行モード/m に影響しないアンカー記号「A」「z」 my if if if } $str = "abracadabra"; ($str =~ /Aabra/) { print "okn" } ($str =~ /abraz/) { print "okn" } ($str =~ /Aabracadabraz/) { print "okn" ; my if if if $str say = "abracadabra"; ~~ /^abra/ { say "ok" } ~~ /abra$/ { say "ok" } ~~ /^abracadabra$/ { "ok" ; } 33

スペースのマッチ Perl 5 Perl 6 / /x /Q E/x /[ trn]+/x / / /<'

スペースのマッチ Perl 5 Perl 6 / /x /Q E/x /[ trn]+/x / / /<' '>/ /<space>/ /<ws>/ my $str = "This ista n pen. "; if ($str =~ / This is /x) { print "okn" } if ($str =~ / This Q E is /x) { print "okn" } if ($str =~ / is [ trn] a /x) { print "okn" } if ($str =~ / a [ trn]+ pen /x) { print "okn" } my $str = "This ista n pen if $str ~~ / This is / { say "ok" } if $str ~~ / This <' '> is / { say "ok" } if $str ~~ / is <space> a / { say "ok" } if $str ~~ / a <ws> pen / { say "ok" } . "; 35

/e 修飾子の廃止 Perl 6 Perl 5 s/pattern/code/e s/pattern/{code}/ sub cm 2 inch { my

/e 修飾子の廃止 Perl 6 Perl 5 s/pattern/code/e s/pattern/{code}/ sub cm 2 inch { my ($cm) = @_; sprintf('%. 01 f-inch', $cm / 6. 5); } my $floppy = "3. 5 -inch FDD"; if ($floppy =~ s/(d+. d+)-inch/{ sprintf('%. 02 f-cm', $1 * 6. 5) }/ex) { if ($floppy eq "22. 75 -cm FDD") { print "okn" } if ($floppy =~ s/(d+. d+)-cm/{ &cm 2 inch($1) }/ex) { if ($floppy eq "3. 5 -inch FDD") { print "okn" } } } sub cm 2 inch($cm) { sprintf('%. 01 f-inch', $cm / 6. 5); } my $floppy = "3. 5 -inch FDD"; if $floppy ~~ s/(d+. d+)-inch/{ sprintf('%. 02 f-cm', $0 * 6. 5) }/ { if $floppy eq "22. 75 -cm FDD" { say "ok" } if $floppy ~~ s/(d+. d+)-cm/{ &cm 2 inch($0) }/ { if $floppy eq "3. 5 -inch FDD" { say "ok" } } } Cf. Acme: : Hyde(単位変換) on CPAN 37

新しい修飾子の書き方 Perl 5 Perl 6 m/pattern/i m: i/pattern/ m/pattern/g m: e/pattern/ s/pattern/replace/ig s: i:

新しい修飾子の書き方 Perl 5 Perl 6 m/pattern/i m: i/pattern/ m/pattern/g m: e/pattern/ s/pattern/replace/ig s: i: e/pattern/replace/ my $imas = "とかしつくして"; if ($imas =~ s/し/ち/g) { if $imas ~~ s: g/し/ち/ { if ($imas eq "とかちつくちて") { または m: each/pattern/ if $imas eq "とかちつくちて" { print "okn"; say "ok"; } } または m: ignorecase/pattern/ } } 38

空白マッチ修飾子: w Perl 6 Perl 5 m/foos+bar/ m/s*foos+bars*/ m: w/foo bar/ m: w/ foo

空白マッチ修飾子: w Perl 6 Perl 5 m/foos+bar/ m/s*foos+bars*/ m: w/foo bar/ m: w/ foo bar / Perl 6 では、スペースとコメントが自由に挿入できるモード/x がデフォルトになったため 正規表現中にスペースを書いても無視されてしまう. . .        whitespaceを有効にする空白マッチ修飾子: w my $str = "begin: foo bar t baz n end"; if ($str =~ m/(foo s+ bar)/x) { if ($1 eq "foo my $str = "begin: foo bar t baz n end"; if $str ~~ m: w/(foo bar)/ { bar") { print "okn" } if $0 eq "foo bar" { say "ok" } } } if ($str =~ m/(s* foo s+ bar s*)/x) { if $str ~~ m: w/( foo bar )/ { if ($1 eq " foo } bar t ") { print "okn" } if $0 eq " foo bar t " { say "ok" } } 39

キャプチャを伴わない括弧 […] Perl 6 Perl 5 (? : pattern) [pattern] my @domain = (

キャプチャを伴わない括弧 […] Perl 6 Perl 5 (? : pattern) [pattern] my @domain = ( "shibuya. pm. org", "shibuya. pl" , "shibuyajs. org" , ); for (@domain) { if (/^(w+)(? : . |-)? (js|pm|pl)(? : . org)? $/) { print "Hello, $1 $2 !n"; } } my @domain = ( "shibuya. pm. org", "shibuya. pl" , "shibuyajs. org" , ); for @domain { if /^(w+) [. |-]? (js|pm|pl) [. org]? $/ { say "Hello, $0 $1 !"; } } ドメイン名からコミュニティ名を判断し "Hello, shibuya pm !" と挨拶する 42

文字クラスの定義 <[a-z]> Perl 6 Perl 5 [abc] [a-z] [^xyz] [B-Y] <[abc]> <[a-z]> <-[xyz]> <

文字クラスの定義 <[a-z]> Perl 6 Perl 5 [abc] [a-z] [^xyz] [B-Y] <[abc]> <[a-z]> <-[xyz]> < <[A-Z]> - <[AZ]> > my @files = ("Jcode. pm", "Encode. pm", "jcode. pl"); foreach (@files) { for @files { if / ( [J|En|j] code . p<[ml]> ) / { if (/ ( (? : J|En|j) code . p[ml]) /x ) { if $_ eq $0 { say "ok" } if ($_ eq $1) { print "okn" } } } "Jcode. pm", "Encode. pm", "jcode. pl" のどれにもマッチする正規表現 44

変数展開 <$var> Perl 5 Perl 6 / $var /x / <$var> / my $var

変数展開 <$var> Perl 5 Perl 6 / $var /x / <$var> / my $var = "(This|That) is a (pen|book)"; my $text 1 = "This is a pen"; my $text 2 = "That is a book"; if ($text 1 =~ /$var/) { if ($text 1 ~~ m: w/<$var>/) { say "ok"; print "okn"; } } if ($text 2 =~ /$var/) { if ($text 2 ~~ m: w/<$var>/) { say "ok"; print "okn"; } } ※Perl 6 Specs よりサンプル作成 46

文字列 <'string'> のリテラル展開 Perl 5 Perl 6 Q$varE $var QstringE <'string'> $QstringE <'$string'> my

文字列 <'string'> のリテラル展開 Perl 5 Perl 6 Q$varE $var QstringE <'string'> $QstringE <'$string'> my $err = "Can't locate Boofy. pm in @INC"; my $soozy = "Boofy. pm"; if ($err =~ /Q$soozyE/x) { print "okn"; } if ($err =~ /@INC/x) { print "okn"; } my $err = "Can't locate Boofy. pm in @INC"; my $soozy = "Boofy. pm"; if $err ~~ /$soozy/ { say "ok"; } if $err ~~ /<'@INC'>/ { say "ok"; } ※Perl 6 Specs よりサンプル作成 47

文字列配列 @str のリテラル展開 Perl 6 Perl 5 $target ~~ / (? : Q$str[0]E |

文字列配列 @str のリテラル展開 Perl 6 Perl 5 $target ~~ / (? : Q$str[0]E |         Q$str[1]E | … ) /x my @str = ("orz", "OTL", "_|~|-O"); my $food = "pasta mista, peperini, capellini tagliati, orzi piccoli, stelline. "; if ($food =~ /(? : Q$str[0]E | Q$str[1]E | Q$str[2]E )/x) { print "okn"; } $target ~~ / @str / my @str = ("orz", "OTL", "_|~|-O"); my $food = "pasta mista, peperini, capellini tagliati, orzi piccoli, stelline. "; if $food ~~ / @str / { say "ok"; } ※Perl 6 Specs よりサンプル作成 48

コードの実行 {code} Perl 6 Perl 5 /pat(? {code})tern/ # 埋め込みコード /pat{code}tern/ /pat(? ? {retcode})tern/

コードの実行 {code} Perl 6 Perl 5 /pat(? {code})tern/ # 埋め込みコード /pat{code}tern/ /pat(? ? {retcode})tern/ # 動的正規表現 /pat<{retcode}>tern/ どこでもクロージャ{. . . } my $text = "pattern"; $text =~ m/pat(? {print "okn"})tern/; $text ~~ m/pat{say "ok"}tern/; if ($text =~ m/pat(? ? {lc("TER")})n/) { if $text ~~ m/pat<{lc("TER")}>n/ { say "ok"; print "okn"; } } ※Perl 6 Specs よりサンプル作成 50

正規表現のライブラリ化 Perl 6 Rules grammar Perl 6: : Rule { rule pattern { <term>+?

正規表現のライブラリ化 Perl 6 Rules grammar Perl 6: : Rule { rule pattern { <term>+? } rule term { <comment> | <alternation> | <non_alternation> } rule comment { # N* } rule alternation { <non_alternation> | <term>+? } rule non_alternation { … } } $source_code ~~ / <Perl 6: : Rule. pattern> /; 54

Example Target strings # lib/My. Project/Test. pm http: //search. cpan. org/~ingy/Test-Base/lib/Test/Base. pm Perl 6

Example Target strings # lib/My. Project/Test. pm http: //search. cpan. org/~ingy/Test-Base/lib/Test/Base. pm Perl 6 code grammar Test: : Base: : Spec { package My. Project: : Test; use Test: : Base -Base; use My. Project; … package My. Project: : Test: : Filter; use Test: : Base: : Filter -base; sub my_filter { return My. Project->do_something(shift); } rule spec { <block>* } rule block { <head> <comment> <section>* } rule head { <block_delim> [ <sp>+ <name> ]? n } # t/sample. t use My. Project: : Test; plan tests => 1 * blocks; rule comment { [ <!section_delim> <line> ]* } run_is input => 'expected'; sub local_filter { s/my/your/; } rule section { <section_delim> <sp>+ <name> <sp>+ [ <filter> <sp>+ ]* [ ': ' <data> n | n <chunk> ] } __END__ === Test one (the name of the test) --- input my_filter local_filter my input lines --- expected output === Test two This is an optional description of this particular test. --- input my_filter other input lines --- expected other expected output rule block_delim { === } rule section_delim { --- } rule line { name { data { filter N* n } N* } { S+ } rule chunk { [ <!block_delim> <!section_delim> <line> ]* } } 55

Perl 5 互換の正規表現 Perl 5 Perl 6 m/old_pattern/i m/(? i)old_pattern/ m: perl 5/old_pattern/ m:

Perl 5 互換の正規表現 Perl 5 Perl 6 m/old_pattern/i m/(? i)old_pattern/ m: perl 5/old_pattern/ m: perl 5: i/old_pattern/ m: perl 5/(? i)old_pattern/ my $var = "(This|That) is a (pen|book)"; my $text 1 = "This is a pen"; my $text 2 = "That is a book"; if ($text 1 =~ /$var/) { if ($text 1 ~~ m: w/<$var>/) { say "ok"; print "okn"; } } if ($text 2 =~ /$var/) { if ($text 2 ~~ m: w/<$var>/) { say "ok"; print "okn"; } } Perl 5 の正規表現でも書けるので、ご安心を 57

参考URL n Perl 6 rules - Wikipedia n http: //en. wikipedia. org/wiki/Perl_6_rules n perl

参考URL n Perl 6 rules - Wikipedia n http: //en. wikipedia. org/wiki/Perl_6_rules n perl 6: Apocalypse 5: Pattern Matching (Larry Wall) n http: //dev. perl. org/perl 6/doc/design/apo/A 05. html n perl 6: Synopsis 5: Regexes and Rules (Damian Conway) n http: //dev. perl. org/perl 6/doc/design/syn/S 05. html n Perl 6 FAQ - Regexes and Grammars n http: //www. programmersheaven. com/2/Perl 6 -FAQ-Regex n Perl 6: : Rules - Implements (most of) the Perl 6 regex syntax n http: //search. cpan. org/~dconway/Perl 6 -Rules/Rules. pm n 日本語 n Perl 6 Rules(新たな正規表現) n http: //www 9. ocn. ne. jp/~ymt/perl 6/rules. html 60

Software Design 2007年 2月号 http: //labs. cybozu. co. jp/blog/takesako/2007/01/perl 6 software_design_20072. html 61

Software Design 2007年 2月号 http: //labs. cybozu. co. jp/blog/takesako/2007/01/perl 6 software_design_20072. html 61

62

62

63

63

Enjoy Perl 6 Have fun! s/ Perl 5 Regular Expression / Perl 6 Regex

Enjoy Perl 6 Have fun! s/ Perl 5 Regular Expression / Perl 6 Regex and Rules /mixes; 65