ref: 鬼車 正規表現 Version 5.9.1
ref: Ruby Freaks Lounge: 第6回 Ruby M17N 事始め:正規表現編
\g 㨠\k ã«ã¤ãã¦ä»ã¾ã§ã¡ããã¨ããã£ã¦ãªãã£ãããã©ãå°ãããã£ããããªæ°ã«ãªã£ãã®ã§ã¡ã¢ãRuby ã¨ãããã鬼è»ã®è©±ãªã®ã§ãPHP ã§ã使ãããããããªãã試ãã¦ãªããã©ã
ç°ä¸å²ã¹ãã·ã£ã« \g ã®åºæ¬
\g ã§åç §ãããæ¬å¼§ã®ä¸èº«ãããã«ãã®ã¾ã¾æ¸ãããã¨æãã°ããã
re = /\A(?<foo>abc...def)\g<foo>\z/ # \g<foo> ãå±éãã¦èãã # /\A(?<foo>abc...def)abc...def\z/ ã¨åãæå³ p "abc123defabc123def".match(re) # ããã p "abc123defabc456def".match(re) # ããã p "abc123def" .match(re) # éããã
\g ã¯å帰çã«åç §ã§ãã
èªåèªèº«ã \g ã§å帰çã«åç §ãããã¨ãã§ãããç¸äºå帰ãå¯è½ã
re = /\A(?<foo>abc\g<foo>|def)\z/ # 'abc' \g<foo> ã 'def' ã«ããããã # /\A(abc)*def\z/ ã¨åãæå³ p "def" .match(re) # ããã p "abcdef" .match(re) # ããã p "abcabcdef".match(re) # ããã p "abc" .match(re) # éããã
æ¬å¼§ã®å¯¾å¿å¤å®
\g ã®å帰ã使ã£ã¦ãæ¬å¼§ã®å¯¾å¿ãå¤å®ã§ããã
re = /\A(?<foo>\(\g<foo>*\))\z/ # '(' \g<foo> ')' ã空æååã«ããããã p "()" .match(re) # ããã p "(()())".match(re) # ããã p "(()()" .match(re) # éããã
åæå¤å® (ãã® 1)
0 㨠1 ãããªãæååãåæã«ãªã£ã¦ãããã©ããã
re = /\A(?<foo>0\g<foo>0|1\g<foo>1|)\z/ p "00" .match(re) #=> ããã p "0110" .match(re) #=> ããã p "01000010".match(re) #=> ããã p "0100001" .match(re) #=> éããã
ããããåæå¤å®ã¯ãé決å®æ§ããã·ã¥ãã¦ã³ãªã¼ãããã³ (æèèªç±ææ³ã¨ç価) ã§ã¯å¤å®ã§ããããã©ã決å®æ§ããã·ã¥ãã¦ã³ãªã¼ãããã³ (æèèªç±ææ³ããã¯å°ãã) ã§å¤å®ã§ããªãåé¡ãããã§ã (参考) *1 ã確ãã«ãæèèªç±ææ³ã®è¦åãã®ã¾ã¾ã£ã¦æãã§ãããã
S -> 0S0 | 1S1 | ε
ã¡ãªã¿ã«ã0 㨠1 ã ãã§ãªããä»»æã®æåã«ã¤ãã¦ã®åæå¤å®ãã§ãããå¾è¿°ã
å¾æ¹åç § \k ã®åºæ¬
\k ã§æ示ãããæ¬å¼§ã«ãããããæååã«ãããããã\1 ã \2 ã¨åãã
re = /\A(?<foo>abc...def)\k<foo>\z/ # /\A(abc...def)\1\z/ ã¨åãæå³ p "abc123defabc123def".match(re) # ããã p "abc123defabc456def".match(re) # éããã
\k ã¯ãã¹ãã¬ãã«ãæå®ã§ãã
ãããé£ããã\g ã¯å帰çã«åç
§ã§ãããã®å帰ã«ã¯ã³ã¼ã«ã¹ã¿ãã¯ã®ãããªãã®ããã (ãã¹ãã¬ãã«ã¨ãããã) ã\k 㯠\k
re = /\A(?<foo>(?<bar>.)\g<foo>|\k<bar-1>)\z/ p "abca".match(re) # éããã p "abcb".match(re) # éããã p "abcc".match(re) # ããã re = /\A(?<foo>(?<bar>.)\g<foo>|\k<bar-2>)\z/ p "abca".match(re) # éããã p "abcb".match(re) # ããã p "abcc".match(re) # éããã re = /\A(?<foo>(?<bar>.)\g<foo>|\k<bar-3>)\z/ p "abca".match(re) # ããã p "abcb".match(re) # éããã p "abcc".match(re) # éããã
æåã«ãããããä¾ ("abcc".match(re)) ã§ã¯ã以ä¸ã®ããã«ããããé²ãã§ãããã¨æãã
- ãã¹ãã¬ãã« 0 ã(?
.)\g ãé¸æããã¦ã'a' ã bar ã«æç¸ããããfoo ãå帰çã«å¼ã³åºã (ãã¹ãã¬ãã«ãä¸ãã) ã - ãã¹ãã¬ãã« 1 ã(?
.)\g ãé¸æããã¦ã'b' ã bar ã«æç¸ããããfoo ãå帰çã«å¼ã³åºã (ãã¹ãã¬ãã«ãä¸ãã) ã - ãã¹ãã¬ãã« 2 ã(?
.)\g ãé¸æããã¦ã'c' ã bar ã«æç¸ããããfoo ãå帰çã«å¼ã³åºã (ãã¹ãã¬ãã«ãä¸ãã) ã - ãã¹ãã¬ãã« 3 ã(?
.)\g ãé¸æããã¦ã'c' ã bar ã«æç¸ããããfoo ãå帰çã«å¼ã³åºã (ãã¹ãã¬ãã«ãä¸ãã) ã - ãã¹ãã¬ãã« 4 ãããæåããªãã®ã§ (?
.)\g ã«ã \k ã«ããããããªããããã¯ãã©ãã¯ã§ãã¹ãã¬ãã« 4 ãæããã - ãã¹ãã¬ãã« 3 ã\k
ãé¸æãããã\k ã¯ããç¾å¨ã®ãã¹ãã¬ãã« - 1ãã®ãã¹ãã¬ãã«ã§ bar ã«æç¸ãããæååã«ããããããããã§ã¯ãã¹ãã¬ãã« 2 (= 3 - 1) ã§æç¸ããã 'c' ã®ãã¨ãä¸è´ããã®ã§ããããè¿ãã
ã¡ãªã¿ã« \k
åæå¤å® (ãã® 2)
ãã¹ãã¬ãã«ä»ãã® \k ã使ãã¨ãä»»æã®æåã®åæå¤å®ãã§ããã
re = /\A(?<foo>(?<bar>.)\g<foo>\k<bar+0>|)\z/ # (?<bar>.)\g<foo>\k<bar+0> ã空æååã«ããããã p "1234554321" .match(re) #=> ããã p "123123321321".match(re) #=> ããã p "123455432" .match(re) #=> éããã
対å¿ãã (?
ã¡ãªã¿ã«ãããã \k
XML (ã¿ãããªãã®) ã®å¤å®
ã¨ã¦ããããããã
re = %r(\A (?<name> \w+ ){0} (?<stag> < \g<name> > ){0} (?<etag> </ ( \k<name+1> | dummy ) >){0} (?<element> \g<stag> \g<element>? \g<etag> ){0} \g<element> \z)x p re.match("<foo><bar><baz></baz></bar></foo>") #=> ããã p re.match("<foo><bar><baz></baz></bar></BOO>") #=> éããã
ããããªã \k
... --- element -+- stag --- name | +- etag ^ N-1 ^ N ^ N+1 <== ãã¹ãã¬ãã«
etag ã®ãã¹ãã¬ãã« N ããè¦ãã¨ãããã«å¯¾å¿ãã name ã®ãã¹ãã¬ãã«ã¯ N + 1 ãå¥ã®è¨ãæ¹ãããã¨ããetag ã®ãã¹ãã¬ãã« + 1ã=ãelement ã®ãã¹ãã¬ãã« + 2ã=ãstag ã®ãã¹ãã¬ãã« + 1ã=ãname ã®ãã¹ãã¬ãã«ãã¨ãããã¨ãã ã¨æãã
ä½è«: å·¦å帰ã¯ç¦æ¢
\g ã¯å帰ã§ãããã©ãå·¦å帰ã¯ã§ããªãã
/(?<foo>x|\g<foo>\+\g<foo>)/ #=> never ending recursion: /(?<foo>x|\g<foo>\+\g<foo>)/
ãªãã§ãã¨è¨ãããã¨ãæ£ç´ããããã£ã¦ãªãã®ã§å°ãã
ä½è«: åãååãè¤æ°ãã£ãå ´å
ãªããªãæ°æã¡æªãããã©ãåãååãåããã¹ãã¬ãã«ã«è¤æ°åå®ç¾©ã§ããããã®ååã \k ã§åç §ããå ´åã¯ãã©ããã¨ä¸è´ããã°ãããããã¿ããã
re = /\A(?<foo>.)(?<foo>.)\k<foo>\k<foo>\z/ p "abaa".match(re) # ããã p "abab".match(re) # ããã p "abba".match(re) # ããã p "abbb".match(re) # ããã p "abbc".match(re) # éããã
ã¾ã¨ã
ããããããã ããã
*1:ãã®ãããããã鬼è»ã®æ£è¦è¡¨ç¾ã¯æèèªç±ææ³ãå å«ãããã¨æããããããããããã¨ãLALR ã¯æ±ºå®æ§ããã·ã¥ãã¦ã³ãªã¼ãããã³ããå¼±ããããã®ã§ã鬼è»ã®æ£è¦è¡¨ç¾ã¯ yacc ãããã¶ãå¼·ãããããããããããªããªã