92
Perl 6 正規表現プログラミング 楽土入門 サボウズ・ラボ株式会社 竹迫 良範 <[email protected]>

Perl6 Regex Programming with Rakudo

Embed Size (px)

DESCRIPTION

YAPC::Asia 2010 Tokyo Day 2 (Yoshinori TAKESAKO)

Citation preview

Page 1: Perl6 Regex Programming with Rakudo

Perl 6 正規表現プログラミング楽土入門

サボウズ・ラボ株式会社

竹迫 良範

<[email protected]>

Page 2: Perl6 Regex Programming with Rakudo

2009/04/06 Cybozu University 2

自己紹介

Page 3: Perl6 Regex Programming with Rakudo

Shibuya Perl Mongers 2代目リーダー

いまここ

Page 4: Perl6 Regex Programming with Rakudo

2009/04/06 Cybozu University 4

My Parrot

Page 5: Perl6 Regex Programming with Rakudo

My pretty Parrot (Cockatiel) 可愛的小奧姆

Moshi-moshi ?

My Parrot can say “Hello” when the telephone rang.

Page 6: Perl6 Regex Programming with Rakudo

另外的 Parrot 算術擅長

Parrot Assembler (PASM)

PASM

set I1, 33set I2, 5mod I3, I1, I2if I3, REMA print "5 is an integer divisor of 33" branch DONE

REMA: print "5 divides 33 with remainder " print I3

DONE: print "¥n" end

33÷5=6、余り2 を計算する

(5 into 33 is 6, remainder 2)

Page 7: Perl6 Regex Programming with Rakudo

Perl6 の実装方針(最初の戦略)

Parrot

Perl6 を Parrot で書く

Perl5 を Parrot で動くようにする (Ponie Project)

Page 8: Perl6 Regex Programming with Rakudo

2009/04/06 Cybozu University 8

Perl 5 is alive.

But …

Page 9: Perl6 Regex Programming with Rakudo

Perl 5 “Hello, world!”

package Earth;sub Greet{

%_=('Y','~');$_='$;=!(Middle

Earth.age~~~<Eart~~~~~~~~~~~~~h

.age)?!(defined$ti~~~~~~~~~~~mez~~~On

e[2])?!(push@time~~~~~~~~~~~~~~~~Zone,loc

~altime())?rotation?~~~~~~~~~~~~~q~~?The Worl

~~d?:q:[¥w]::q=[¥~~~~~~~~~~~~~~~~~d~a-f]=:q?..~~

~~~?:q:.:;"42b3d3~~~~~~~~~~~~~~~~~~~~~728656c6c6f6

~~~~~0277f627c64672~~~~~~~~~~~~~~~~~~~~~b3072796e647

~~~~~~~42b3b3rg7d"=Ym~~~~~~~~~~~~~~~~~~~¥$;~~*¥;p~~~~u

~~~~~~~~~sh@_,$&;bless~~~~~~~~~~~~~~~~~~~~~~~~~$c~~~~~~~

~~~~~~~~~o~ntine~~~~~nt~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~~~~~s=¥~~~~~~~$~~~~~~~~~~~~~~~~~~~~~~~pangaea~~~~

~~~~~~~~~~~~~~~;{l~~~~~~~~~~~~~~~~~~~~~~~~~~~~ocal@_;local$;

~~~~~~~~~~~~~~~~~="o~~~~~~~~~~~~~~~~~~~~~~~~~cean";$^A=(defi

~~~~~~~~~~~~~~~~~~~n~~~~~~~~~~~~~~~~~~~~~~~~~ed$continents)?

~~~~~~~~~~~~~~~~~~~(vec(~~~~~~~~~~~~~~~~~~~~~~$;, YYsplit(¥'

~~~~~~~~~~~~~~~~~¥',${¥$;}~~~~~~~~~~~~~~~~~~~~~~)%3,YYsplit(

~~~~~~~~~~~~~~~~q??,$;)**2-~~~~~~~~~~~~~~~~~~~~~~(($;=Ytr/oa

~~~~~~~~~~~~~~~~eiu//)**2))=~~~~~~~~~~~~~~~~~~~~~~=28160)?q:

~~~~~~~~~~~~~~~~~.::q?!?:¥'?~~~~~~~~~~~~~~~~~~~~~~¥';}$^A=Ys

~~~~~~~~~~~~~~~~:¥Q.¥E:pack(~~~~~~~~~~~~~~~~~~~~~~¥'h*¥',j

~~~~~~~~~~~~~~~~~oin(q(),~~~~~~~~~~~~~~~~~~~~~~~grep{$_=

~~~~~~~~~~~~~~~~~~Ym,$,,}~~~~~~~~~~~~~~~~~~~~~~~split("

~~~~~~~~~~~~~~~~~",@_~~~~~~~~~~~~~~~~~~~~~~~~~~[0]))

~~~~~~~~~~~~~~~~):e~~~~~~~~~~~~~~~~~~~~~~~~~~~gexe

~~~~~~~~~~~~~~~;$d~~~~~~~~~~~~~~~~~~~~~~~~~~~="s

~~~~~~~~~~~~~~ort~~~~~~~~~~~~~~~~~~~~~~~~~~<=

~~~~~~~~~~~~>,~~~~~~~~~~~~~~~~~~~~~~~~~~YY

~~~~~~~~~~~@_~~~~~~~~~~~~~~~~~~~~~~~~

~~~~~~~~~"~~~~~~~~~~~~~~~~~~~';;

s,(~|¥r|¥n|¥s),,g;s.Y.¥x7e.g;

eval};Greet;'the world';

http://www.perlmonks.org/index.pl?node_id=329174 by jbware on Feb 15, 2004 at 21:08 UTC (#329174=obfuscated)

Page 10: Perl6 Regex Programming with Rakudo

Unreadable

Perl5→読みにくいプログラムを量産し続けるPerl5

Page 11: Perl6 Regex Programming with Rakudo

Readable

Perl6!読みやすいプログラムを書けるPerl6になる!

Page 12: Perl6 Regex Programming with Rakudo

Perl 6 では・・・

ね、簡単でしょ?

say "Hello, world!";

Page 13: Perl6 Regex Programming with Rakudo

2009/04/06 Cybozu University 13

Perl 6on

Parrot

Page 14: Perl6 Regex Programming with Rakudo

這個 Parrot 能說各種各樣的語言

Page 15: Perl6 Regex Programming with Rakudo
Page 16: Perl6 Regex Programming with Rakudo

O’REILLY

Page 17: Perl6 Regex Programming with Rakudo

NOT’REALLY

Page 18: Perl6 Regex Programming with Rakudo
Page 19: Perl6 Regex Programming with Rakudo

2000

Page 20: Perl6 Regex Programming with Rakudo

Perl6 言語仕様 (language specification)

1. Apocalypse(黙示録)

Larry Wall が Perl6 のデザンについて語る

Perl6 の歴史的な文書(33個のRFCがベース)

2. Exegesis(注釈)

Perl6 を用いたサンプルコードや Perl5 との比較

黙示録を Damian Conway が詳細に解説

3. Synopsis(概要)

Perl6 の最新の言語仕様が書かれている

黙示録のダジェスト版

Page 21: Perl6 Regex Programming with Rakudo

Why Perl 6 ? (モチベーション)

Perl 5 は・・・場当たり的な拡張を繰り返し

既に Perl5 のコードは理解不能な領域にC でゴリゴリ 職人技 (needs more C hacker)

Perl 6 の目指す方向せめて OO らしく

他の言語で良いところは取り入れよう

後方互換性は無視

コンパラと実行環境の分離Parrot で VM 化

No more C hacker

Page 22: Perl6 Regex Programming with Rakudo

all your language are belong to us

- Project Perl 6 -

Page 23: Perl6 Regex Programming with Rakudo

Second System Syndrome (The Mythical Man-Month)

2度目にデザンするシステムは失敗作になりやすい説

1度目のデザンは自分の能力を把握していないので慎重に

3度目のデザンは何が普遍的で何が特殊なものか分かるので正確に作ることができる

しかし2度目のデザンでは、最初のデザンで抑えたゕデゕ・装飾を思い切り詰め込んでしまうので失敗作になりやすい

人月の神話―狼人間を撃つ銀の弾はない

ISBN: 4894716658→ Perl6 は構想10年!

Page 24: Perl6 Regex Programming with Rakudo

・・・

Page 25: Perl6 Regex Programming with Rakudo

2005

Page 26: Perl6 Regex Programming with Rakudo

救世主 Pugs の登場

Pugs = Perl6 User’s Golfing System

Yet another Perl6 implementation

→ Perl6 が動いた!2005/02/06 (1|2)+(3|4)→(4|5|6)

Page 27: Perl6 Regex Programming with Rakudo

Audrey Tang (唐鳳)

CPAN界隈で有名

PARの作者

1981年生まれ

国籍:台湾

http://en.wikipedia.org/wiki/Audrey_Tang

高橋メソッドを世界に輸出した人

Perl6(Pugs)を Haskell で実装した天才プログラマー

Page 28: Perl6 Regex Programming with Rakudo

Pugs の拡張性

powered by

Haskell

Page 29: Perl6 Regex Programming with Rakudo

2010

Page 30: Perl6 Regex Programming with Rakudo

待望の Perl6 – Rakudo Star リリース!

Page 31: Perl6 Regex Programming with Rakudo

http://rakudo.org/

Page 32: Perl6 Regex Programming with Rakudo

http://github.com/rakudo/star/downloads

Page 33: Perl6 Regex Programming with Rakudo

Get your own Parrot!

Page 34: Perl6 Regex Programming with Rakudo

34

Page 35: Perl6 Regex Programming with Rakudo

5秒でわかる Perl 6

メソッドを -> ではなく . で書けるようになった

Perl 5

$obj->method();

Perl 6

$obj.method();

→ これで Perl も立派なOO言語の仲間入り!

Page 36: Perl6 Regex Programming with Rakudo

36

The End

終了

Page 37: Perl6 Regex Programming with Rakudo

Perl 6 で失ったもの ~後方互換性~

文字列の連結 .(ドット)→ ~(チルダ)に

Perl5

# メソッド呼び出し

$obj->method();

sub func { return "x"; }

# 文字列の連結

my $a = "str";my $b = $a.func();

Perl6

一時期 ” _ ” という案もあったが…スペース入れるのが面倒

# メソッド呼び出し

$obj.method();

sub func { return "x"; }

# 文字列の連結

my $a = "str";my $b = $a~func();

Page 38: Perl6 Regex Programming with Rakudo

subst 文字列の置換

Rakudo/bin/ufo より

sub path-to-module-name($path) {$path.subst(/^'lib/'/, '') ¥

.subst(/¥.pm6?$/, '') ¥

.subst('/', '::', :g) ;}

Page 39: Perl6 Regex Programming with Rakudo

OO

Page 40: Perl6 Regex Programming with Rakudo

Perl 5

Sigils

Page 41: Perl6 Regex Programming with Rakudo

$ @ %

Page 42: Perl6 Regex Programming with Rakudo

配列とハッシュのゕクセス方法が変更

はじめての人にもわかりやすく

変数のプレフゖクス $@% ルールが変更

Perl5 Perl6

my @array = (1, 2, 3);my %hash = ('a'=> 1);

# 配列のメンバにアクセスmy $x = $array[0];

# ハッシュのメンバにアクセスmy $y = $hash{'a'}

my @array = (1, 2, 3);my %hash = ('a'=> 1);

# 配列のメンバにアクセスmy $x = @array[0];

# ハッシュのメンバにアクセスmy $y = %hash{'a'}

Page 43: Perl6 Regex Programming with Rakudo

Perl 5 の変数(sigils rules)

scalar array hash

------- ------ -------

$s @a %h

$$s $a[0] $h{'?'}

$s->foo ☹ ☹

Page 44: Perl6 Regex Programming with Rakudo

Perl 6 の変数(Sigils rule)

scalar array hash

------- ------ -------

$s @a %h

$$s @a[0] %h<?>

$s.foo @a.foo %h.foo

Page 45: Perl6 Regex Programming with Rakudo

() 括弧省略

if, for, while, do ブロックでの(括弧省略)

キータプの量が少なくなった

Perl5 Perl6

if ($a eq $b) {print "a=b¥n";

}

while ($i > 0) {$i--;

}

if $a eq $b {say "a=b";

}

while $i > 0 {$i--;

}

Page 46: Perl6 Regex Programming with Rakudo

Perl5 Perl6

# スペースなしprint(1+2)*3;

# スペースなしprint(1+2)*3;

(例)

スペースのあり/なしで実行結果が違う

# スペースありprint (1+2)*3;

# スペースありprint (1+2)*3;

→ 実行結果: 3 → 実行結果: 3

→ 実行結果: 3 → 実行結果: 9

Page 47: Perl6 Regex Programming with Rakudo

Neko operator(範囲演算子)

Damian Conway氏が OSCON2005 で発音

http://www.rubyist.net/~matz/20050803.html

末尾を含まない「..^」

先頭を含まない「^..」

先頭と末尾を含まない「^..^」

Perl6

my @a = (1..^5); # (1,2,3,4)my @b = (1^..5); # (2,3,4,5)my @c = (1^..^5); # (2,3,4)

Page 48: Perl6 Regex Programming with Rakudo

ネコ演算子って・・・ちょwおまwww

neko operator

^..^

ネコ耳モード♪

Damian Conway 日本の漫画好き?

http://www.amazon.co.jp/dp/4847034864/

Page 49: Perl6 Regex Programming with Rakudo

49

Please give me!

zip でくれ

Page 50: Perl6 Regex Programming with Rakudo

使用例:zip でくれ

Page 51: Perl6 Regex Programming with Rakudo

便利な zip

2つの配列を同時にループ

順番を保存した重複する key と value の表現

Perl5 Perl6

my @key = ("x", "y", "x");my @value = (1, 2, 3);

for (my $i=0; $i<@key; $i++) {my $a = $key[$i];my $b = $value[$i];print "key:$a; value:$b¥n";

}

my @key = ("x", "y", "x");my @value = (1, 2, 3);

for zip(@key,@value) -> $a,$b {print "key:$a; value:$b¥n";

}

Page 52: Perl6 Regex Programming with Rakudo

実際には Z operator が使える

Rakudo では zip ではなく Z 演算子が実装

(1,2) Z (3,4) (1,3, 2,4)

Rakudo Perl6

my @key = ("x", "y", "x");my @value = (1, 2, 3);

for @key Z @value -> $a,$b {print "key:$a; value:$b¥n";

}

my @key = ("x", "y", "x");my @value = (1, 2, 3);

for zip(@key,@value) -> $a,$b {print "key:$a; value:$b¥n";

}

Page 53: Perl6 Regex Programming with Rakudo

Piping operators(<==, ==>)

Perl6

@result = map { floor($^x / 2) }

grep { /^ ¥d+ $/ }

@data;

@result <== map { floor($^x / 2) }

<== grep { /^ ¥d+ $/ }

<== @data;

@data ==> grep { /^ ¥d+ $/ }

==> map { floor($^x / 2) }

==> @result;

Page 54: Perl6 Regex Programming with Rakudo

// 演算子(err 演算子)

左辺が undef のときのみ右辺を評価

// defined or

Perl5 でありがちなバグを回避

0(ゼロ) や ”” (空文字列)の扱い

それぞれ || → or, // → err に対応

Perl5 Perl6

$num = shift @ARGV || 1;

$bar = func() or die;

$num = shift @ARGS // 1;

$bar = func() err die;

Page 55: Perl6 Regex Programming with Rakudo

// は C言語で単一行コメント(PL/I起源)

/* C comment style */// #include <stdio.h>

必ず Syntax Error になる記号

# Shell - single line comment

# Perl - single line comment

Page 56: Perl6 Regex Programming with Rakudo

JavaScript // problem

var r = new RegExp(“pattern”);

var r = /pattern/;

これは何?

//

// start a single-line comment.

To specify an empty regular expression,

use /(?:)/

Page 57: Perl6 Regex Programming with Rakudo

57

Perl 5 Perl 6

正規表現

別の言語

Page 58: Perl6 Regex Programming with Rakudo

Perl5 正規表現 Perl6 Regex で変わるもの

1. 基本パターン繰り返し *+? と選択 |

2. マッチ演算子文字列のパターンマッチ m//スマートマッチ演算子 ~~文字列の置換 s///

3. 修飾子複数行モード/m 修飾子の廃止文字列の先頭「¥A」末尾「¥z」の廃止スペースとコメントが自由に挿入できるモード/x がデフォルトに単一行モード/s の廃止 /e 修飾子の廃止新しい修飾子の書き方

Page 59: Perl6 Regex Programming with Rakudo

Perl5 正規表現 Perl6 Regex で変わるもの

4. キャプチャ

キャプチャ括弧(…)と後方参照

キャプチャを伴わない括弧 […]

5. メタキャラクタ

文字クラスの定義 <[a-z]>

定義済み文字クラスの参照 <class>

変数展開 <$var>

文字列 <'string'> のリテラル展開

文字列配列 @strings のリテラル展開

Page 60: Perl6 Regex Programming with Rakudo

Perl5 正規表現 Perl6 Regex の未来

6. クロージャ

コードの実行 {code}

マッチ失敗 {fail}

繰り返し範囲 **{n..m}

7. ルール

rule

grammar

Page 61: Perl6 Regex Programming with Rakudo

61

1. 基本パターン

Page 62: Perl6 Regex Programming with Rakudo

62

繰り返し *+? と選択 |

Perl 5 Perl 6

/x*/ # xが0個以上繰り返し

/y+/ # yが1個以上繰り返し

/z?/ # zが0個以上1個以下

/foo|bar/ # fooまたはbar

/x*/ # == Perl 5

/y+/ # == Perl 5

/z?/ # == Perl 5

/foo|bar/ # == Perl 5

$_ = "aaa bbb ccc foo moo zoo";

if (/aaax*/) { print "ok¥n" }

if (/b+/) { print "ok¥n" }

if (/cccc?/) { print "ok¥n" }

if (/foo|bar|baz/) { print "ok¥n" }

$_ = "aaa bbb ccc foo moo zoo";

if /aaax*/ { say "ok" }

if /b+/ { say "ok" }

if /cccc?/ { say "ok" }

if /foo|bar|baz/ { say "ok" }

Page 63: Perl6 Regex Programming with Rakudo

63

2. マッチ演算子

Page 64: Perl6 Regex Programming with Rakudo

文字列のパターンマッチ m//

Perl 5 Perl 6

/pattern/

m/pattern/

m{pattern}

qr/pattern/

$_ = "This is a pen.";

if (/This/) { print "ok¥n" }

if (m/pen/) { print "ok¥n" }

if (m{pen}) { print "ok¥n" }

unless (/not match/) { print "ok¥n" }

if ($_ =~ qr/pen/) { print "ok¥n" }

$_ = "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" }

/pattern/

m/pattern/

m{pattern}

rx/pattern/ または regex{pattern}

Page 65: Perl6 Regex Programming with Rakudo

スマートマッチ演算子 ~~

Perl 5 Perl 6

$str =~ /pattern/$str !~ /pattern/

$str ~~ /pattern/$str !~~ /pattern//pattern/ ~~ $str/pattern/ !~~ $str

my $str = "This is a pen.";

if ($str =~ /This/) { print "ok¥n" }

if ($str =~ m/pen/) { print "ok¥n" }

## (m/pen/ =~ $str) とは書けない

if ($str !~ /not match/) { print "ok¥n" }

unless ($str ~~ /not match/) { print "ok¥n" }

my $str = "This is a pen.";

if $str ~~ /This/ { say "ok" }

if $str ~~ m/pen/ { say "ok" }

if m/pen/ ~~ $str { say "ok" }

if $str !~~ /not match/ { say "ok" }

unless $str ~~ /not match/ { say "ok" }

Page 66: Perl6 Regex Programming with Rakudo

66

3. 修飾子

Page 67: Perl6 Regex Programming with Rakudo

複数行モード/m 修飾子の廃止

Perl 5 Perl 6

/^ pattern $/m /^^ pattern $$/

my $lines = "aaa¥nbbb¥nccc¥n";

if ($lines =~ /^b/m) { print "ok¥n" }

if ($lines =~ /bb$/m) { print "ok¥n" }

if ($lines =~ /^bbb$/m) {

print "ok¥n";

}

my $lines = "aaa¥nbbb¥nccc¥n";

if $lines ~~ /^^b/ { say "ok" }

if $lines ~~ /bb$$/ { say "ok" }

if $lines ~~ /^^bbb$$/ {

say "ok" ;

}

正規表現の修飾子/mで「^」と「$」のマッチ規則が変わる

Page 68: Perl6 Regex Programming with Rakudo

文字列の先頭「¥A」末尾「¥z」の廃止

Perl 5 Perl 6

/¥A pattern ¥z/ /^ pattern $/

my $str = "abracadabra";

if ($str =~ /¥Aabra/) { print "ok¥n" }

if ($str =~ /abra¥z/) { print "ok¥n" }

if ($str =~ /¥Aabracadabra¥z/) {

print "ok¥n" ;

}

my $str = "abracadabra";

if $str ~~ /^abra/ { say "ok" }

if $str ~~ /abra$/ { say "ok" }

if $str ~~ /^abracadabra$/ {

say "ok" ;

}

複数行モード/m に影響しないゕンカー記号「¥A」「¥z」

Page 69: Perl6 Regex Programming with Rakudo

スペースとコメントが自由に挿入できるモード/x がデフォルトに

Perl 5 Perl 6

/ pattern1 # コメントをここに書く

pattern2 pattern3

/x

/ pattern1 # コメントをここに書く

pattern2 pattern3

/

my $str = "abracadabra";

if ( $str =~ / abra # ゕブラca # カ

d abra # ダブラ/x # 終了

) { print "ok¥n" }

if ($str =~ / abra cad abra /x) { print "ok¥n" }

my $str = "abracadabra";

if ( $str ~~ / abra # ゕブラca # カ

d abra # ダブラ/ # 終了

) { say "ok" }

if $str ~~ / abra cad abra / { say "ok" }

Page 70: Perl6 Regex Programming with Rakudo

スペースのマッチ

Perl 5 Perl 6

/¥ /x

/¥Q ¥E/x

/[ ¥t¥r¥n]/x

/[ ¥t¥r¥n]+/x

/¥ /

/<' '>/

/<space>/

/<ws>/

my $str = "This is¥ta ¥n pen.";

if ($str =~ / This ¥ is /x)

{ print "ok¥n" }

if ($str =~ / This ¥Q ¥E is /x)

{ print "ok¥n" }

if ($str =~ / is [ ¥t¥r¥n] a /x)

{ print "ok¥n" }

if ($str =~ / a [ ¥t¥r¥n]+ pen /x)

{ print "ok¥n" }

my $str = "This is¥ta ¥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" }

Page 71: Perl6 Regex Programming with Rakudo

単一行モード/s の廃止

Perl 5 Perl 6

/./s # どんな文字(改行を含む)

/./ # どんな文字も(改行は除く)

/[¥x0D¥x0A]|¥x0D¥x0A/

/./ # 改行を含むどんな文字

/¥N/ # 改行以外のどんな文字も

/¥n/ # どんな端末の改行にもマッチ

my $c = '/************************ This is a C comment ************************/#include <stdio.h>/* first */main() { printf("C"); }';

if ($c =~ m/(¥/¥*.+?¥*¥/)/) {if ($1 eq "/* first */") { print "ok¥n" }

}if ($c =~ m/(¥/¥*.+?¥*¥/)/s) {

my $lines = $1;if ($lines =~ /comment/) { print "ok¥n" }

}

my $c = '/************************ This is a C comment ************************/#include <stdio.h>/* first */main() { printf("C"); }';

if $c ~~ m{( ¥/¥* ¥N+? ¥*¥/ )} {if $0 eq "/* first */" { say "ok" }

}if $c ~~ m{( ¥/¥* [.|¥n]+? ¥*¥/ )} {

my $lines = $0;if $lines ~~ /comment/ { say "ok" }

}

Page 72: Perl6 Regex Programming with Rakudo

/e 修飾子の廃止 どこでも {code}

Perl 5 Perl 6

s/pattern/code/e s/pattern/{code}/

sub cm2inch {

my ($cm) = @_;

sprintf('%.01f-inch', $cm / 6.5);

}

my $floppy = "3.5-inch FDD";

if ($floppy =~ s/(¥d+¥.¥d+)-inch/{ sprintf('%.02f-cm',

$1 * 6.5) }/ex) {

if ($floppy eq "22.75-cm FDD") { print "ok¥n" }

if ($floppy =~ s/(¥d+¥.¥d+)-cm/{ &cm2inch($1) }/ex) {

if ($floppy eq "3.5-inch FDD") { print "ok¥n" }

}

}

sub cm2inch($cm) {

sprintf('%.01f-inch', $cm / 6.5);

}

my $floppy = "3.5-inch FDD";

if $floppy ~~ s/(¥d+¥.¥d+)-inch/{ sprintf('%.02f-cm', $0 * 6.5) }/ {

if $floppy eq "22.75-cm FDD" { say "ok" }

if $floppy ~~ s/(¥d+¥.¥d+)-cm/{ &cm2inch($0) }/ {

if $floppy eq "3.5-inch FDD" { say "ok" }

}

}

cf. Acme::Hyde(単位変換) on CPAN

Page 73: Perl6 Regex Programming with Rakudo

新しい修飾子の書き方

Perl 5 Perl 6

m/pattern/i

s/pattern/replace/ig

m/:i pattern/

s:g/pattern/replace/

my $imas = "とかしつくして";

if ($imas =~ s/し/ち/g) {

if ($imas eq "とかちつくちて") {

print "ok¥n";

}

}

my $imas = "とかしつくして";

if $imas ~~ s:g/し/ち/ {

if $imas eq "とかちつくちて" {

say "ok";

}

}

Page 74: Perl6 Regex Programming with Rakudo

74

4. キャプチャ

Page 75: Perl6 Regex Programming with Rakudo

キャプチャ括弧(…)と後方参照

Perl 5 Perl 6

(…)〃¥1〃¥2〃¥3… (…)〃$0〃$1〃$2…

my $str = "abracadabra";

if ($str =~ /(a)br¥1c/) { print "ok¥n" }

if ($str =~ /(ab)racad$1ra/) { print "ok¥n" }

if ($str =~ /(a)(b)r$1c$2d$2$2ra/) {

print "ok¥n" ;

}

if ($1 eq "a") { print "ok¥n" }

if ($2 eq "b") { print "ok¥n" }

my $str = "abracadabra";

if $str ~~ /(a)br$0c/ { say "ok" }

if $str ~~ /(ab)racad$0ra/ { say "ok" }

if $str ~~ /(a)(b)r$0c$0d$0$1ra/ {

say "ok" ;

}

if ($0 eq "a") { say "ok" }

if ($1 eq "b") { say "ok" }

日本円¥廃止

ドル$決済でゼロスタート

括弧(…)でキャプチャして、同じ正規表現内で後方参照する

【覚え方】

Page 76: Perl6 Regex Programming with Rakudo

キャプチャを伴わない括弧 […]

Perl 5 Perl 6

(?: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 !" と挨拶する

Page 77: Perl6 Regex Programming with Rakudo

77

5. メタキャラクタ

Page 78: Perl6 Regex Programming with Rakudo

文字クラスの定義 <[a-z]>

Perl 5 Perl 6

[abc]

[a-z]

[^xyz]

[B-Y]

<[abc]>

<[a-z]>

<-[xyz]>

< <[A-Z]> - <[AZ]> >

my @files = ("Jcode.pm", "Encode.pm", "jcode.pl");

foreach (@files) {

if (/ ( (?:J|En|j) code ¥. p[ml]) /x ) {

if ($_ eq $1) { print "ok¥n" }

}

}

my @files = ("Jcode.pm", "Encode.pm", "jcode.pl");

for @files {

if / ( [J|En|j] code ¥. p<[ml]> ) / {

if $_ eq $0 { say "ok" }

}

}

"Jcode.pm", "Encode.pm", "jcode.pl" のどれにもマッチする正規表現

Page 79: Perl6 Regex Programming with Rakudo

文字クラスの定義 <[a-z]>

Perl 5 Perl 6

¥x20 # 空白1文字¥s+ # 連続したスペース¥. # ドット

[[:digit:]] # [0-9][[:upper:]] # [A-Z][[:lower:]] # [a-z][[:alpha:]] # [A-Za-z][[:alnum:]] # [A-Za-z0-9]

<space> # 空白1文字<ws> # 連続したスペース<dot> # ドット ※ <lt>, <gt><digit> # 数字<upper> # 英大文字<lower> # 英小文字<alpha> # ゕルフゔベット<alnum> # ゕルフゔベットと数字

$_ = "123 abc ¥t 456 ijk ¥t 789 XYZ";

if (/ ([0-9]+) ¥ ([A-Za-z]+) /x) {

if ($1 eq "123" && $2 eq "abc") { print "ok¥n" }

}

if (/ ([A-Za-z]+) ¥s+ ([0-9]+) /x) {

if ($1 eq "abc" && $2 eq "456") { print "ok¥n" }

}

$_ = "123 abc ¥t 456 ijk ¥t 789 XYZ";

if / (<digit>+) ¥ (<alpha>+) / {

if $0 eq "123" && $1 eq "abc" { say "ok" }

}

if / (<alpha>+) <ws> (<digit>+) / {

if $0 eq "abc" && $1 eq "456" { say "ok" }

}

Page 80: Perl6 Regex Programming with Rakudo

変数展開 <$var>

Perl 5 Perl 6

/ $var /x / <$var> /

my $var = "(This|That) is a (pen|book)";

my $text1 = "This is a pen";

my $text2 = "That is a book";

if ($text1 =~ /$var/) {

print "ok¥n";

}

if ($text2 =~ /$var/) {

print "ok¥n";

}

my $var =

"(This|That)<space>is<space>a<space>(pen|book)";

my $text1 = "This is a pen";

my $text2 = "That is a book";

if ($text1 ~~ m/<$var>/) {

say "ok";

}

if ($text2 ~~ m/<$var>/) {

say "ok";

}

Page 81: Perl6 Regex Programming with Rakudo

文字列 <'string'> のリテラル展開

Perl 5 Perl 6

¥Q$var¥E

¥Qstring¥E

¥$¥Qstring¥E

$var

<'string'>

<'$string'>

my $err = "Can't locate Boofy.pm in ¥@INC";

my $soozy = "Boofy.pm";

if ($err =~ /¥Q$soozy¥E/x) {

print "ok¥n";

}

if ($err =~ /¥@INC/x) {

print "ok¥n";

}

my $err = "Can't locate Boofy.pm in ¥@INC";

my $soozy = "Boofy.pm";

if $err ~~ /$soozy/ {

say "ok";

}

if $err ~~ /<'@INC'>/ {

say "ok";

}

Page 82: Perl6 Regex Programming with Rakudo

文字列配列 @str のリテラル展開

Perl 5 Perl 6

$target ~~ / (?: ¥Q$str[0]¥E |

¥Q$str[1]¥E | … ) /x

$target ~~ / @str /

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 "ok¥n";

}

my @str = ("orz", "OTL", "_|~|-O");

my $food = "pasta mista, peperini,

capellini tagliati,

orzi piccoli, stelline.";

# Rakudo では未実装っぽい

if $food ~~ / @str / {

say "ok";

}

Page 83: Perl6 Regex Programming with Rakudo

83

6. クロージャ

Page 84: Perl6 Regex Programming with Rakudo

どこでもコード実行 {code}

Perl 5 Perl 6

/pat(?{code})tern/ # 埋め込みコード

/pat(??{retcode})tern/ # 動的正規表現

/pat{code}tern/

/pat<{retcode}>tern/

my $text = "pattern";

$text =~ m/pat(?{print "ok¥n"})tern/;

if ($text =~ m/pat(??{lc("TER")})n/) {

print "ok¥n";

}

my $text = "pattern";

$text ~~ m/pat{say "ok"}tern/;

if $text ~~ m/pat<{lc("TER")}>n/ {

say "ok";

}

どこでもクロージャ{...}

Page 85: Perl6 Regex Programming with Rakudo

マッチ失敗 {fail}

Perl 5 Perl 6

/ (...) {fail} /

my $x = qr/(25[0-5]|(?:2[0-4]|1[0-9]|[1-9])?[0-9])/;

for (0..255) {

/^($x)$/;

}

my $addr = "192.168.1.33";

if ($addr =~ /^($x¥.$x¥.$x¥.$x)$/) {

print "ok¥n";

}

my $x = / (¥d+) {fail if $0 > 255} /;my $ipv4 = /^ $x ¥. $x ¥. $x ¥. $x $/;my $addr = "192.168.1.33";if $addr ~~ /$ipv4/ {

say "ok";}

正規表現のクロージャ内で fail を呼ぶと〃現在のキャプチャ内のマッチに失敗させることができる。これを応用すると、正規表現中に複雑な計算式やプログラムを組み込んでパターンマッチさせられる。

【例】 IPアドレスをチェックする正規表現

[これは便利]

Page 86: Perl6 Regex Programming with Rakudo

86

7. ルール

Page 87: Perl6 Regex Programming with Rakudo

正規表現のラブラリ化

Perl 6 Rules & Grammars

grammar Inventory {

regex product { ¥d+ }

regex quantity { ¥d+ }

regex color { ¥S+ }

regex description { ¥N* }

regex TOP { ^^ <product> ¥s+ <quantity> ¥s+

[

| <description> ¥s+ '(' ¥s* <color> ¥s* ')'

| <color> ¥s+ <description>

]

$$

}

Inventory.parse($source_lines);

Page 88: Perl6 Regex Programming with Rakudo

Example

Target strings Perl 6 code# lib/MyProject/Test.pm

package MyProject::Test;use Test::Base -Base;use MyProject;…package MyProject::Test::Filter;use Test::Base::Filter -base;sub my_filter {

return MyProject->do_something(shift);}

# t/sample.tuse MyProject::Test;

plan tests => 1 * blocks;

run_is input => 'expected';

sub local_filter {s/my/your/;

}

__END__

=== Test one (the name of the test)--- input my_filter local_filtermyinputlines--- expectedexpectedoutput=== Test twoThis is an optional descriptionof this particular test.--- input my_filterotherinputlines--- expectedother expectedoutput

grammar Test::Base::Spec {

rule spec { <block>* }

rule block {<head><comment><section>*

}

rule head {<block_delim> [ <sp>+ <name> ]? ¥n

}

rule comment {[ <!section_delim> <line> ]*

}

rule section {<section_delim><sp>+ <name><sp>+ [ <filter> <sp>+ ]*[ ':' <data> ¥n | ¥n <chunk> ]

}

rule block_delim { ¥=¥=¥= }rule section_delim { ¥-¥-¥- }

rule line { ¥N* ¥n }rule name { ¥N* }rule data { ¥N* }rule filter { ¥S+ }

rule chunk {[ <!block_delim> <!section_delim> <line> ]*

}

}

http://search.cpan.org/~ingy/Test-Base/lib/Test/Base.pm

Page 89: Perl6 Regex Programming with Rakudo

89

Named capture など

まだまだ紹介しきれない

便利な機能がいっぱい!

Page 90: Perl6 Regex Programming with Rakudo

90

さらに詳しく

Page 91: Perl6 Regex Programming with Rakudo

参考URL

Perl 6 rules - Wikipedia http://en.wikipedia.org/wiki/Perl_6_rules

perl6: Apocalypse 5: Pattern Matching (Larry Wall)

http://dev.perl.org/perl6/doc/design/apo/A05.html

perl6: Synopsis 5: Regexes and Rules (Damian Conway)

http://dev.perl.org/perl6/doc/design/syn/S05.html

Perl 6 FAQ - Regexes and Grammars http://www.programmersheaven.com/2/Perl6-FAQ-Regex

Perl6::Rules - Implements (most of) the Perl 6 regex syntax http://search.cpan.org/~dconway/Perl6-Rules/Rules.pm

日本語 Perl6 Rules(新たな正規表現)

http://www9.ocn.ne.jp/~ymt/perl6/rules.html

Page 92: Perl6 Regex Programming with Rakudo

92

Have fun!

Enjoy Perl 6

Perl 6 正規表現プログラミング楽土入門