目次トップへ | |||
はじめに
| |||
全能な正規表現トップへ(??{ code }) (?{ code }) マッチしない正規表現トップへ(?!) ある文字列とある文字列を含むものにマッチする正規表現トップへ(?=.*foo)(?=.*bar) (?=.*foo)(?=.*bar)(?=.*hoge) ある文字列を含まないものにマッチする正規表現トップへ(?:(?!foo).)* | |||
正規表現で不定方程式を解くトップへ# solve for 12x + 15y + 16z = 281, maximizing x if (($X, $Y, $Z) = (('o' x 281) =~ /^(o*)\1{11}(o*)\2{14}(o*)\3{15}$/)) { ($x, $y, $z) = (length($X), length($Y), length($Z)); print "One solution is: x=$x; y=$y; z=$z.\n"; } else { print "No solution.\n"; } 実行結果: % perl diophantine-equations.pl One solution is: x=17; y=3; z=2. 正規表現で素因数分解するトップへ# [regexp 23]より # Perl Cookbook のコードをわずかに修正した (途中経過を出力) while (<>) { chomp; for ($N = ('o' x $_); $N =~ /^(oo+?)\1+$/; $N =~ s/$1/o/g) { print length($1), " $N // ", length($N), "\n"; } print length($N), " $N // ", length($N), "\n"; print "\n"; } 実行例: % perl prime-pattern.pl 30 2 oooooooooooooooooooooooooooooo // 30 3 ooooooooooooooo // 15 5 ooooo // 5 54 2 oooooooooooooooooooooooooooooooooooooooooooooooooooooo // 54 3 ooooooooooooooooooooooooooo // 27 3 ooooooooo // 9 3 ooo // 3 回文にマッチする正規表現トップへ# 再帰版 $palindrome = qr{ (\w) (\w|(??{$palindrome})*) \1 }x; /^$palindrome$/# 全能版 ^(\w+)\w?(??{reverse $1})$ | |||
入れ子を許した括弧内を削除するトップへ1 while $str =~ s/\([^()]*\)//g; 入れ子を許した括弧内にマッチさせるトップへ$openclose = qr/\([^()]*(?:(??{$openclose})[^()]*)*\)/; while ($str =~ /($openclose)/g) { print $1, "\n"; } タグの外側だけ対象に置換するトップへs/((?:\G|>)[^<]*?)foo/$1bar/g; | |||
タグの閉じ忘れをチェックするトップへopen(PERL, '< perl.htm') or die "perl.htm: $!\n"; { local $/ = undef; $html = <PERL>; } close(PERL); while ($html =~ /(<(NOBR|CODE|B|PRE|FONT)\b # ある開始タグから (?:(?!<\/\2>).)* # そのタグが閉じられる前に (?:<\2>|$))/sigx) { # また開始タグor終わり print $1, "\n"; } XMLタグを加工するトップへ<?xml version="1.0"?> <div class="memo"> <div class="author"> <div class="name">okabe</div> </div> <div class="subject">test</div> <div class="body"> <div class="paragraph"> This is a <div class="emphasis">sample</div> script. </div> </div> </div> というxmlファイルを <?xml version="1.0"?> <memo> <author> <name>okabe</name> </author> <subject>test</subject> <body> <paragraph> This is a <emphasis>sample</emphasis> script. </paragraph> </body> </memo> という形に変換する. 1 while ($this =~ s/<div\sclass="([^"]+)"> ((?:(?!<div).)*?) <\/div>/<$1>$2<\/$1>/xsg); my @name; $this =~ s/<div\sclass="([^"]+)">(?{push(@name, $1)}) | <\/div>/$1 ? "<$1>" : "<\/@{[pop(@name)]}>"/xge; | |||
xy を含まないものにマッチする正規表現トップへ[regexp 60]より 遷移図が書ければ答は求まるのですが、結局 [^x] x . <----+ <----+ <----+ | | | | | | \/ x \/ y \/ 0 ----> 1 ----> 2 | | | [^xy] | <----------+ です。 0から始まって2で終るのが「xy を含む」ということですから、求めるも のはその否定すなわち、0か1が終了状態の DFA です。 で、素朴なアルゴリズムで解くと「xy を含まない文字列」は ([^x]|x+[^xy])*x* が答です。他には | を展開して [^x]*(x+[^xy][^x]*)*x* とか、 *y(x*[^xy]y*)*x* とかがあります。 |fmcat =(retofm <<<'(x+y+a)*xy(x+y+a)*'|fmcment) =(retofm <<<'xy')|fmdeterm|fmmin|fmtore|perl -pe 'y/+/|/; s/a/[^xy]/g' |として |([^xy]|y)*x(x|[^xy]([^xy]|y)*x)*y grail 連立方程式では p = p[^x] + q[^xy] + ε q = px + qx を解いて、答は p + q。 xyz を含まないものにマッチする正規表現トップへ[regexp 60]より |fmcat =(retofm <<<'(x+y+z+a)*xyz(x+y+z+a)*'|fmcment) =(retofm <<<'xyz')|fmdeterm|fmmin|fmtore|perl -pe 'y/+/|/; s/a/[^xyz]/g' |として、 |([^xyz]|y|z)*x(z([^xyz]|y|z)*x|[^xyz]([^xyz]|y|z)*x|x|yx|y[^xyz]([^xyz]|y|z)*x|yy([^xyz]|y|z)*x)*yz 遷移図は x <-----------+ [^x] | x | <----+ <----+ | | | | | | \/ x \/ y | z 0 ----> 1 ----> 2 ----> 3(DEAD) | | | | [^xy] | | <----------+ | | [^xz] | <--------------------- 「xyz を含まない文字列」の答は、 ([^x]|x(y?x)*([^xy]|y[^xz]))*(x(y?x)*x?)? (x(y?x)*x?)? の部分はこの場合に限り (x|y)* で代用できるかな 後、つるかめ算の様に「勘」で書いたのが [^x]*(x+(y|y[^xz][^x]*|[^xy][^x]*))* ですがちょっと自信無し | |||
式を簡略化するトップへ↓こんな式を ^((b)|(a)((aa)|bb)*((ab)|ba))(((bb)|aa)|((ba)|ab)((aa)|bb)*((ab)|ba))*$ ↓こんな感じに簡略化したい ^(b|a(aa|bb)*(ab|ba))(aa|bb|(ab|ba)(aa|bb)*(ab|ba))*$sub simplify { my $expr = shift; $openclose = qr/[^()]*(?:\((??{$openclose})\)[^()]*)*/; $no_or = qr/[^(|)]*(?:\((??{$openclose})\)[^(|)]*)*/; $term = qr/(?:(?:\w+|\((??{$term})(?:\|(??{$term}))*\))\*?)/; use re 'eval'; 1 while (0 or $expr =~ s/\((\w)\)/$1/g or # (a)→a $expr =~ s/\(($no_or)\)(?![*?])/$1/g or # (expr)→expr $expr =~ s/^\(($openclose)\)$/$1/g or # ^(expr)$→expr $expr =~ s/\((\($openclose\))\)/$1/g or # ((expr))→(expr) $expr =~ s/((?:^|\()(?:$term+\|)*) \( ($term+(?:\|$term+)+) \) ((?:\|$term+)*(?:\)|$))/$1$2$3/gx or # (expr1|(expr2|expr3))→(expr1|expr2|expr3) $expr =~ s/\((\w)[*?]\)\*/$1*/g or # (a[*?])*→a* $expr =~ s/\((\w)\*\)[*?]/$1*/g or # (a*)[*?]→a* $expr =~ s/(\w)[*?]\1\*/$1*/g or # a[*?]a*→a* $expr =~ s/(\w)\*\1[*?]/$1*/g or # a*a[*?]→a* $expr =~ s/\(($openclose)\)[*?]\(\1\)\*/($1)*/g or # (expr)[*?](expr)*→(expr)* $expr =~ s/\(($openclose)\)\*\(\1\)[*?]/($1)*/g or # (expr)*(expr)[*?]→(expr)* $expr =~ s/\((\($openclose\))[*?]\)\*/$1*/g or # ((expr)[*?])*→(expr)* $expr =~ s/\((\($openclose\)\*)\)[*?]/$1/g or # ((expr)*)[*?]→(abc)* $expr =~ s/(^|[(|])($no_or)((?:\|$no_or)*)\|\2($|[|)])/$1$2$3$4/ or # expr1|expr2|expr1→expr1|expr2 $expr =~ s/(^|[(|])($no_or)\|($no_or)($|[|)]) (?(?{(length $2 > length $3 or (length $2 == length $3 and ($2 cmp $3) > 0)) })|(?!))/$1$3|$2$4/x or # expr1|expr2→sort(expr1|expr2) 0); no re 'eval'; $expr; } タグを無視して折り返すトップへ基本的に指定バイト数で<BR>を挿入 日本語に対応(文字化けしないように多バイト文字を分割しない) タグは無視して折り返しバイト数を数える 元から<BR>が入っている場合にも対応 タグの中で間違って折り返さない$html = 'あaい<FOO>う<BAR>え<FOO>おかき<BR>くけaこ<FOO><BAR>さaしすせそたちつてとな<123456789012345>に'; $maxBytes = 10; # 指定バイト数 # EUC-JP文字 $ascii = '[\x00-\x7F]'; # 1バイト EUC-JP文字 $twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'; # 2バイト EUC-JP文字 $threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト EUC-JP文字 $character = "(?:$ascii|$twoBytes|$threeBytes)"; # EUC-JP文字 $skip = qr/(?>(?:(?!<BR>)<[^>]*>)*)/; use re 'eval'; $html =~ s/\G((?:<[^>]*>|(?!<)$character)*?) ((?: $skip ((?!<BR>)$character) (?{local $len = $len + length($3)}) )*?) (?(?=$skip($character)) (?(?{$maxBytes >= $len and $len > $maxBytes - length($4)})|(?!))) (?!<BR>|$) /$1$2<BR>/xigo; no re 'eval'; print $html, "\n"; | |||
禁則処理しつつ折り返すトップへPerlメモの禁則処理しつつ折り返すスクリプトと 同等の機能を正規表現で実現するrequire 'jcode.pl'; # EUC-JP文字 $ascii = '[\x00-\x7F]'; # 1バイト EUC-JP文字 $twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'; # 2バイト EUC-JP文字 $threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト EUC-JP文字 $character = "(?:$ascii|$twoBytes|$threeBytes)"; # EUC-JP文字 $space = '(?:\s|\xA1\xA1)'; # 削除する行頭行末空白 $no_begin = "!%),.:;?]}¢°’”‰′″℃、。々〉》」』】〕" . "ぁぃぅぇぉっゃゅょゎ゛゜ゝゞァィゥェォッャュョヮヵヶ" . "・ーヽヾ!%),.:;?]}"; # 行頭禁則文字 $no_begin_jisx0201 = "。」、・ァィゥェォャュョッー゛゜"; jcode::z2h_euc(\$no_begin_jisx0201); $no_begin .= $no_begin_jisx0201; # 行頭禁則文字(半角カタカナ) $no_end = "\$([{£\‘“〈《「『【〔$([{¥"; # 行末禁則文字 $no_end_jisx0201 = "「"; jcode::z2h_euc(\$no_end_jisx0201); $no_end .= $no_end_jisx0201; # 行末禁則文字(半角カタカナ) $allow_end = $no_begin; # ぶら下げ行頭禁則文字 $no_begin1 = '[' . join('', map {quotemeta} grep {defined} $no_begin =~ /(?:($ascii)|$twoBytes|$threeBytes)/xg) . ']'; $no_begin2 = '(?:' . join('|', grep {defined} $no_begin =~ /(?:$ascii|($twoBytes)|$threeBytes)/xg) . ')'; $no_end1 = '[' . join('', map {quotemeta} grep {defined} $no_end =~ /(?:($ascii)|$twoBytes|$threeBytes)/xg) . ']'; $no_end2 = '(?:' . join('|', grep {defined} $no_end =~ /(?:$ascii|($twoBytes)|$threeBytes)/xg) . ')'; $no_begin = '(?:' . join('|', map {quotemeta} $no_begin =~ /$character/g) . ')'; $allow_end = $no_begin; # ぶら下げ行頭禁則文字 sub fold_properly { my $str = shift; ($basesize, $maxsize) = @_; # グローバル変数にしないと途中で変更できない use re 'eval'; $str =~ tr/\t\n\r\f/ /; # 空白文字をスペースに変換 $str =~ s/^$space+//o; # 行頭空白削除 ($folded, undef, $str) = $str =~ /^ (($character*(?<!$no_end1)(?<!$no_end2)) # 行末禁則チェック # 基本長チェック (?(?{length($2) - ($2 =~ tr|\x8E||) > $basesize})(?!)) $allow_end*?) # ぶら下げ (?<!$no_end1)(?<!$no_end2) # 行末禁則チェック(ぶら下げ含) # 最大長チェック (?(?{length($1) - ($1 =~ tr|\x8E||) > $maxsize})(?!)) (?(?<=\w)(?!\w)) # 単語分割しない ((?!$space*$no_begin)$character*?)$/xo; # 行頭禁則チェック ($folded, $str) = $str =~ /^ ($character*) (?(?{length($1) - ($1 =~ tr|\x8E||) > $basesize})(?!)) (.*)$/xo if $folded eq ''; no re 'eval'; $folded =~ s/^($character*?(?=$space))$space+$/$1/ox; # 行末空白削除 ($folded, $str); } $str = 'aこはテストで すなるほどテストです.' x 2; jcode::z2h_euc(\$str); while (length($str)) { (my $folded, $str) = fold_properly($str, 10, 12); print "$folded\n"; } a が偶数個で b が奇数個の文字列にマッチする正規表現トップへ^(b|a(aa|bb)*(ab|ba))(aa|bb|(ab|ba)(aa|bb)*(ab|ba))*$$states = 4; @matrix = ([qw(X X X a b)], # A = Bb + Ca [qw(X X X b a)], # D = Ba + Cb [qw(X a b X X)], # C = Aa + Db [qw(E b a X X)], # B = Ab + Da + e ); sub rsrt { # r = s + rt → r = st* my $j = shift; if ($matrix[$j][$j + 1] ne 'X') { foreach my $i (0 .. $j) { if ($matrix[$j][$i] ne 'X') { $matrix[$j][$i] .= "$matrix[$j][$j + 1]*"; } } } } sub substitute { my $y = shift; foreach my $i (0 .. $y - 1) { foreach my $j (0 .. $y) { if ($matrix[$i][$j] ne 'X') { if ("$matrix[$y][$j]$matrix[$i][$y + 1]" !~ /X/) { $matrix[$i][$j] = "($matrix[$i][$j]|$matrix[$y][$j]$matrix[$i][$y + 1])"; } } else { if ("$matrix[$y][$j]$matrix[$i][$y + 1]" !~ /X/) { $matrix[$i][$j] = "($matrix[$y][$j]$matrix[$i][$y + 1])"; } } } } } sub resolv { for (my $j = $states - 1; $j > 0; $j--) { rsrt($j); substitute($j); } rsrt(0); $matrix[0][0] =~ s/E//g; $matrix[0][0] = '^' . $matrix[0][0] . '$'; } $result = resolv(); $result = simplify($result); print $result; | |||
2 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 2})(?!))$ # 純粋版 8bytes [02468]$ 3 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 3})(?!))$ # 純粋版 109bytes ^(([0369]|[258][0369]*[147])|([147]|[258][0369]*[258])([0369]|[147 ][0369]*[258])*([258]|[147][0369]*[147]))*$[regexp 50]より まず、3 を法として、0 となる数値にマッチする正規表現を p, 1 となる数値 にマッチするものを q, 2 となる数値にマッチするものを r とします。 (まぁ、DFA の各状態に対応する正規表現を考えるわけです。) ここで、p が最終的な答えになるわけですが、まずは、DFA から次のような連 立方程式を作ります。 (1) p = p0 + q2 + r1 + ε (2) q = p1 + q0 + r2 (3) r = p2 + q1 + r0 # ある状態にたどり着くためにはその直前の状態にたどり着いた後に遷移に必 # 要が文字がくればいい、ということが書いてあるだけです。あと、開始状態 # には即座に到達できるので、εを加えます。 で、(3) を r について解きます。 r = (p2 + q1)0* # 一般に r = s + rt は r = st* というように解けます。 ## なるほど!これがポイントですね。Arden の補題というらしいですね。 これを (1) と (2) に代入して r を消去すると次のようになります。 (4) p = p0 + q2 + (p2 + q1)0*1 + ε = p(0 + 20*1) + q(2 + 10*1) + ε (5) q = p1 + q0 + (p2 + q1)0*2 = p(1 + 20*2) + q(0 + 10*2) で、(5) を q について解きます。 q = p(1 + 20*2)(0 + 10*2)* これを (4) に代入して q を消去します。 p = p(0 + 20*1) + p(1 + 20*2)(0 + 10*2)*(2 + 10*1) + ε = p(0 + 20*1 + (1 + 20*2)(0 + 10*2)*(2 + 10*1)) + ε = (0 + 20*1 + (1 + 20*2)(0 + 10*2)*(2 + 10*1))* というわけで答えは (0+20*1+(1+20*2)(0+10*2)*(2+10*1))* です。 Unix 流に書くと + を | に書き換えて (0|20*1|(1|20*2)(0|10*2)*(2|10*1))* となっておしまい、と。# 3 の倍数にマッチする正規表現(109bytes)を求める $states = 3; @matrix = ([qw(E [0369] [258] [147])], # A = A0 + B2 + C1 + e [qw(X [147] [0369] [258])], # B = A1 + B0 + C2 [qw(X [258] [147] [0369])], # C = A2 + B1 + C0 ); $result = resolv(); print $result; | |||
4 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 4})(?!))$ # 純粋版 30bytes ((^|[02468])[048]|[13579][26])$ 5 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 5})(?!))$ # 純粋版 5bytes [05]$ 6 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 6})(?!))$ # 準純粋版 125bytes (?=^\d*[02468]$)^(([0369]|[258][0369]*[147])|([147]|[258][0369]*[2 58])([0369]|[147][0369]*[258])*([258]|[147][0369]*[147]))*$ 7 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 7})(?!))$# 7 の倍数にマッチする正規表現(481,878,604bytes)を求める # 6桁以内の 7 の倍数にマッチする正規表現(117,648bytes) $states = 7; @matrix = ([qw(E a g f e d c b)], # A = Aa + Bg + Cf + De + Ed + Fc + Gb # + e [qw(X b a g f e d c)], # B = Ab + Ba + Cg + Df + Ee + Fd + Gc [qw(X c b a g f e d)], # C = Ac + Bb + Ca + Dg + Ef + Fe + Gd [qw(X d c b a g f e)], # D = Ad + Bc + Cb + Da + Eg + Ff + Ge [qw(X e d c b a g f)], # E = Ae + Bd + Cc + Db + Ea + Fg + Gf [qw(X f e d c b a g)], # F = Af + Be + Cd + Dc + Eb + Fa + Gg [qw(X g f e d c b a)], # G = Ag + Bf + Ce + Dd + Ec + Fb + Ga ); # A B C D E F G @matrix2 = ([qw([07] [18] [29] 3 4 5 6) ], # 1桁目 [qw([07] 5 3 [18] 6 4 [29])], # 2桁目 [qw([07] 4 [18] 5 [29] 6 3) ], # 3桁目 [qw([07] 6 5 4 3 [29] [18])], # 4桁目 [qw([07] [29] 4 6 [18] 3 5) ], # 5桁目 [qw([07] 3 6 [29] 5 [18] 4) ], # 6桁目 ); $result = resolv(); @{$matrix3[5]}[0 .. 6] = @{$matrix2[5]}[0 .. 6]; # 6桁目の計算 for (my $p = 4; $p >= 0; $p--) { # 5桁目から1桁目までを順番に計算 for (my $group = 0; $group < 7; $group++) { $matrix3[$p][$group] = "(^$matrix2[$p][$group]"; for (my $i = 0; $i < 7; $i++) { for (my $j = 0; $j < 7; $j++) { $matrix3[$p][$group] .= '|' . $matrix3[$p + 1][$i] . $matrix2[$p][$j] if $group == ($i + $j) % 7; } } $matrix3[$p][$group] .= ')'; } } if (0) { # 1 なら 6桁以内の 7 の倍数にマッチする正規表現(117,648bytes) $result = '^' . $matrix3[0][0] . '$'; print $result; } else { # 0 なら # 7 の倍数にマッチする正規表現(481,878,604bytes) print ((defined $2) ? $matrix3[0][ord($1) - ord('a')] : $1) while ($result =~ /(([a-g])|.)/g); } | |||
おすすめサイト社内で研修 うさぎ専門店パピーファーム デイリーズをお求めなら オリックス生命のがん保険 税理士ホットライン ネクサーのスマートフォンサイト制作 ポルシェ買取 美容室検索ベストサロンhttp://www.best-salon.net 梅干の河本食品 沖縄青の洞窟でダイビング |
8 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 8})(?!))$ # 純粋版 86bytes ((^|[02468])((^|[048])[08]|[37]2|[26]4[159]6)|[13579]([26][08]|[1 59]2|[048]4|[37]6))$ 9 の倍数にマッチする正規表現トップへ# 全能版 ^(\d+)(?(?{$1 % 9})(?!))$# 9 の倍数にマッチする正規表現(218,457bytes)を求める $states = 9; @matrix = ([qw(E [09] 8 7 6 5 4 3 2 1)], [qw(X 1 [09] 8 7 6 5 4 3 2)], [qw(X 2 1 [09] 8 7 6 5 4 3)], [qw(X 3 2 1 [09] 8 7 6 5 4)], [qw(X 4 3 2 1 [09] 8 7 6 5)], [qw(X 5 4 3 2 1 [09] 8 7 6)], [qw(X 6 5 4 3 2 1 [09] 8 7)], [qw(X 7 6 5 4 3 2 1 [09] 8)], [qw(X 8 7 6 5 4 3 2 1 [09])], ); $result = resolv(); print $result; # $result =~ s/\(/(?:/g; # ( を (?: に変換したら実際に使用できる ISBN にマッチする正規表現トップへ# 全能版 /^(?=\d+X?$|\d+-\d+-\d+-[\dX]$) (\d)-?(\d)-?(\d)-?(\d)-?(\d)-?(\d)-?(\d)-?(\d)-?(\d)-?([\dX]) (?(?{($1 * 10 + $2 * 9 + $3 * 8 + $4 * 7 + $5 * 6 + $6 * 5 + $7 * 4 + $8 * 3 + $9 * 2 + ($10 eq 'X' ? 10 : $10)) % 11})(?!))$/x# 純粋版 # ISBN にマッチする正規表現のサイズを求める $states = 11; # A B C D E F G H I J K @matrix2 = ([qw(0 1 2 3 4 5 6 7 8 9 X) ], # 1桁目 [qw(0 6 1 7 2 8 3 9 4 * 5) ], # 2桁目 [qw(0 4 8 1 5 9 2 6 * 3 7) ], # 3桁目 [qw(0 3 6 9 1 4 7 * 2 5 8) ], # 4桁目 [qw(0 9 7 5 3 1 * 8 6 4 2) ], # 5桁目 [qw(0 2 4 6 8 * 1 3 5 7 9) ], # 6桁目 [qw(0 8 5 2 * 7 4 1 9 6 3) ], # 7桁目 [qw(0 7 3 * 6 2 9 5 1 8 4) ], # 8桁目 [qw(0 5 * 4 9 3 8 2 7 1 6) ], # 9桁目 [qw(0 * 9 8 7 6 5 4 3 2 1) ], # 10桁目 ); for (my $i = 0; $i < $states; $i++) { # 10桁目の計算 $matrix3[9][$i] = length($matrix2[9][$i]) if $matrix2[9][$i] ne '*'; } $result = length('^('); $prev_hyphen = 0; for (my $hyphen = 0; $hyphen < 2; $hyphen++) { # ハイフンなし:0, あり:1 for (my $x = 8; $x >= 2; $x--) { # グループ記号 '-' 出版社記号 for (my $y = $x - 1; $y >= 1; $y--) { # 出版社記号 '-' 書名記号 $result += length('|') if $prev_hyphen == 1; for (my $p = 8; $p >= 0; $p--) { # 9桁目から1桁目までを順番に計算 for (my $group = 0; $group < $states; $group++) { $matrix3[$p][$group] = length(''); $matrix3[$p][$group] += length('('); my $prev = 0; for (my $i = 0; $i < $states; $i++) { for (my $j = 0; $j < $states; $j++) { if ($group == ($i + $j) % $states and $matrix2[$p][$j] ne '*' and $matrix3[$p + 1][$i] != 0) { $matrix3[$p][$group] += length('|') if $prev == 1; $matrix3[$p][$group] += $matrix3[$p + 1][$i]; $matrix3[$p][$group] += length('-') if $hyphen != 0 and ($p == $x or $p == $y or $p == 0); $matrix3[$p][$group] += length($matrix2[$p][$j]); $prev = 1; } } } $matrix3[$p][$group] += length(')'); } } $result += $matrix3[0][0]; $prev_hyphen = 1; last if $hyphen == 0; } last if $hyphen == 0; } } $result += length(')$'); print $result; | ||
文字の正規表現トップへ
|
|
|