現: 2013-06-27 (木) 16:19:54 nao-pon[3] [4] | |||
---|---|---|---|
Line 1: | Line 1: | ||
+ | #navi | ||
+ | RIGHT:&rsslink(../); | ||
+ | #boxdate | ||
+ | * 正規表現処理エンジン PCRE の パータン分析スイッチの有効性について [#h601a971] | ||
+ | RIGHT:&tag(PHP,PCRE,プログラミング,正規表現); | ||
+ | |||
+ | [[イメージマネージャーを使用するにすると更新できなくなります - xpWiki - フォーラム:http://xoops.hypweb.net/modules/forum/index.php?topic_id=3306]] という問題の原因として PCRE の S 修飾子が原因かも、という話が出ました。 | ||
+ | |||
+ | 今まで、特に確信がない正規表現パターンでも、なんとなく効くかもといった理由で、適当に付与していた S 修飾子なのですが、 :hammer: きちんと効くかどうか検証した上で、使用すべきだと痛感しましたので、簡単に検証してみました。 | ||
+ | |||
+ | *** テストスクリプト [#gc6726a2] | ||
+ | |||
+ | xpWiki レンダラーの BB-Code に対応する正規表現をすべて確認。 | ||
+ | #code(php){{ | ||
+ | $str = <<<EOD | ||
+ | (BB-Code を含んだ適当な文章 4,500字程度) | ||
+ | EOD; | ||
+ | $regs = array(); | ||
+ | |||
+ | $regs[] = '/(?:\r\n|\r|\n)?\[code](?:\r\n|\r|\n)?(.*)(?:\r\n|\r|\n)?\[\/code\](?:\r\n|\r|\n)?/sU'; | ||
+ | $regs[] = '/(?:\r\n|\r|\n)?\[code](?:\r\n|\r|\n)?(.*)(?:\r\n|\r|\n)?\[\/code\](?:\r\n|\r|\n)?/sUS'; | ||
+ | |||
+ | $regs[] = '/\[email](.+?)\[\/email]/i'; | ||
+ | $regs[] = '/\[email](.+?)\[\/email]/iS'; | ||
+ | |||
+ | $regs[] = '/\[url=([\'"]?)((?:ht|f)tp[s]?:\/\/[!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/url\]/sU'; | ||
+ | $regs[] = '/\[url=([\'"]?)((?:ht|f)tp[s]?:\/\/[!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/url\]/sUS'; | ||
+ | |||
+ | $regs[] = '/\[url=([\'"]?)([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/url\]/sU'; | ||
+ | $regs[] = '/\[url=([\'"]?)([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/url\]/sUS'; | ||
+ | |||
+ | $regs[] = '/\[siteurl=([\'"]?)\/?([!~*\'();?:\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/siteurl\]/sU'; | ||
+ | $regs[] = '/\[siteurl=([\'"]?)\/?([!~*\'();?:\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\\1\](.+)\[\/siteurl\]/sUS'; | ||
+ | |||
+ | $regs[] = '/(\[quote[^\]]*])(?:\r\n|\r|\n)(?![<>*|,#: \t+-])/'; | ||
+ | $regs[] = '/(\[quote[^\]]*])(?:\r\n|\r|\n)(?![<>*|,#: \t+-])/S'; | ||
+ | |||
+ | $regs[] = '/(?:\r\n|\r|\n)*\[\/quote\]/'; | ||
+ | $regs[] = '/(?:\r\n|\r|\n)*\[\/quote\]/S'; | ||
+ | |||
+ | $regs[] = '/\[img\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U'; | ||
+ | $regs[] = '/\[img\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US'; | ||
+ | |||
+ | $regs[] = '/\[img(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U'; | ||
+ | $regs[] = '/\[img(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US'; | ||
+ | |||
+ | $regs[] = '/\[img\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U'; | ||
+ | $regs[] = '/\[img\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US'; | ||
+ | |||
+ | $regs[] = '/\[img(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U'; | ||
+ | $regs[] = '/\[img(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]([!~*\'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US'; | ||
+ | |||
+ | $regs[] = '/\[siteimg\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]\/?([!~*\'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/U'; | ||
+ | $regs[] = '/\[siteimg\s+align=([\'"]?)(left|center|right)\1(?:\s+title=([\'"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\7)?]\/?([!~*\'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/US'; | ||
+ | |||
+ | $regs[] = '/\[siteimg(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]\/?([!~*\'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/U'; | ||
+ | $regs[] = '/\[siteimg(?:\s+title=([\'"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=([\'"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=([\'"]?)([\d]+?)\5)?]\/?([!~*\'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*\'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/US'; | ||
+ | |||
+ | $regs[] = '/\x01(?:\=([^\]]+))?\](?:\r\n|[\r\n])((?:(?>[^\x01\x02]+)|(?R))*)\x02(?:\r\n|[\r\n]|$)?/'; | ||
+ | $regs[] = '/\x01(?:\=([^\]]+))?\](?:\r\n|[\r\n])((?:(?>[^\x01\x02]+)|(?R))*)\x02(?:\r\n|[\r\n]|$)?/S'; | ||
+ | |||
+ | $_reg = 'test|hoge|fuga'; | ||
+ | |||
+ | $regs[] = '/\[\/?(?:' . $_reg . ')(?:(?: |=)[^\]]+)?\]/'; | ||
+ | $regs[] = '/\[\/?(?:' . $_reg . ')(?:(?: |=)[^\]]+)?\]/S'; | ||
+ | |||
+ | $regs[] = '/\[(' . $_reg . ')(?:\b[^\]]+)?].+\[\/\\1\]/sU'; | ||
+ | $regs[] = '/\[(' . $_reg . ')(?:\b[^\]]+)?].+\[\/\\1\]/sUS'; | ||
+ | |||
+ | $n = 0; | ||
+ | foreach($regs as $reg) { | ||
+ | $n++; | ||
+ | set_time_limit(30); | ||
+ | $start = microtime(true); | ||
+ | for ($i=0; $i < 10000; $i++) { | ||
+ | preg_match($reg, $str); | ||
+ | } | ||
+ | echo $reg; | ||
+ | echo ' : '. (microtime(true) - $start) . '<br>'; | ||
+ | if ($n%2 === 0) echo str_repeat('-', 80).'<br>'; | ||
+ | } | ||
+ | }} | ||
+ | ---- | ||
+ | *** 実行結果 [#b41a236d] | ||
+ | |||
+ | #pre{{ | ||
+ | /(?:\r\n|\r|\n)?\[code](?:\r\n|\r|\n)?(.*)(?:\r\n|\r|\n)?\[\/code\](?:\r\n|\r|\n)?/sU : 5.1569399833679 | ||
+ | /(?:\r\n|\r|\n)?\[code](?:\r\n|\r|\n)?(.*)(?:\r\n|\r|\n)?\[\/code\](?:\r\n|\r|\n)?/sUS : 0.37282490730286 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[email](.+?)\[\/email]/i : 0.24048900604248 | ||
+ | /\[email](.+?)\[\/email]/iS : 0.24318504333496 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[url=(['"]?)((?:ht|f)tp[s]?:\/\/[!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/url\]/sU : 0.23091006278992 | ||
+ | /\[url=(['"]?)((?:ht|f)tp[s]?:\/\/[!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/url\]/sUS : 0.23208713531494 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[url=(['"]?)([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/url\]/sU : 0.23122596740723 | ||
+ | /\[url=(['"]?)([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/url\]/sUS : 0.23223900794983 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[siteurl=(['"]?)\/?([!~*'();?:\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/siteurl\]/sU : 0.31252813339233 | ||
+ | /\[siteurl=(['"]?)\/?([!~*'();?:\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\1\](.+)\[\/siteurl\]/sUS : 0.33435487747192 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /(\[quote[^\]]*])(?:\r\n|\r|\n)(?![<>*|,#: \t+-])/ : 0.3490879535675 | ||
+ | /(\[quote[^\]]*])(?:\r\n|\r|\n)(?![<>*|,#: \t+-])/S : 0.35570693016052 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /(?:\r\n|\r|\n)*\[\/quote\]/ : 3.4016590118408 | ||
+ | /(?:\r\n|\r|\n)*\[\/quote\]/S : 0.36038398742676 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[img\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U : 0.31287097930908 | ||
+ | /\[img\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US : 0.31461405754089 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[img(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U : 0.33726000785828 | ||
+ | /\[img(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US : 0.42045998573303 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[img\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U : 0.31326389312744 | ||
+ | /\[img\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US : 0.31384992599487 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[img(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/U : 0.33749294281006 | ||
+ | /\[img(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]([!~*'();\/?:\@&=+\$,%#_0-9a-zA-Z.-]+)\[\/img\]/US : 0.35765695571899 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[siteimg\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]\/?([!~*'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/U : 0.31132006645203 | ||
+ | /\[siteimg\s+align=(['"]?)(left|center|right)\1(?:\s+title=(['"])?((?(3)[^]]*|[^\]\s]*))(?(3)\3))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\5)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\7)?]\/?([!~*'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/US : 0.31220507621765 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[siteimg(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]\/?([!~*'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/U : 0.3105890750885 | ||
+ | /\[siteimg(?:\s+title=(['"])?((?(1)[^]]*|[^\]\s]*))(?(1)\1))?(?:\s+w(?:idth)?=(['"]?)([\d]+?)\3)?(?:\s+h(?:eight)?=(['"]?)([\d]+?)\5)?]\/?([!~*'();?\@&=+\$,%#_0-9a-zA-Z.-][!~*'();\/?\@&=+\$,%#_0-9a-zA-Z.-]+?)\[\/siteimg\]/US : 0.31125688552856 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\x01(?:\=([^\]]+))?\](?:\r\n|[\r\n])((?:(?>[^\x01\x02]+)|(?R))*)\x02(?:\r\n|[\r\n]|$)?/ : 0.261470079422 | ||
+ | /\x01(?:\=([^\]]+))?\](?:\r\n|[\r\n])((?:(?>[^\x01\x02]+)|(?R))*)\x02(?:\r\n|[\r\n]|$)?/S : 0.261470079422 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[\/?(?:test|hoge|fuga)(?:(?: |=)[^\]]+)?\]/ : 0.42223906517029 | ||
+ | /\[\/?(?:test|hoge|fuga)(?:(?: |=)[^\]]+)?\]/S : 0.42319798469543 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | /\[(test|hoge|fuga)(?:\b[^\]]+)?].+\[\/\1\]/sU : 0.38073801994324 | ||
+ | /\[(test|hoge|fuga)(?:\b[^\]]+)?].+\[\/\1\]/sUS : 0.38188505172729 | ||
+ | -------------------------------------------------------------------------------- | ||
+ | }} | ||
+ | |||
+ | ほとんどのパターンでまるで効果がありませんでした。 | ||
+ | |||
+ | やはり、PHP マニュアル ([[PHP: 正規表現パターンに使用可能な修飾子 - Manual:http://jp2.php.net/manual/ja/reference.pcre.pattern.modifiers.php]]) にある | ||
+ | |||
+ | > | ||
+ | :S| | ||
+ | あるパターンを複数回使用する場合は、マッチングにかかる時間を 高速化することを目的として、パターンの分析に幾分か時間をかけても 良いでしょう。この修飾子を設定すると、追加のパターン分析が 行われます。現在、パターン分析は、最初の文字が単一ではなく、 かつ固定でないパターンに対してのみ有用です。 | ||
+ | |||
+ | '''&font(150%,Blue){&br;最初の文字が単一ではなく、 かつ固定でないパターンに対してのみ有用};''' | ||
+ | |||
+ | この通りですね。 :shy: | ||
+ | |||
+ | |||
+ | RIGHT:&font(90%){&page_comments;}; | ||
+ | #navi |
(This host) = https://xoops.hypweb.net