1 名前:デフォルトの名無しさん mailto:sage [2024/10/29(火) 20:52:19.15 ID:zqRlJI/00.net] !extend::vvvvv:1000:512 !extend::vvvvv:1000:512 ★スレ立て時 ↑ が3行以上になるようコピペ PHPに関する質問スレです 前スレ 【PHP】下らねぇ質問はここに書き込みやがれ 14 https://mevius.5ch.net/test/read.cgi/tech/1663659983/ 次スレは>>980 以降 VIPQ2_EXTDAT: default:vvvvv:1000:512:: EXT was configured
63 名前:デフォルトの名無しさん mailto:sage [2025/05/08(木) 21:51:33.26 ID:MhxTwPG60.net] さて読んでて思ったのだが、これ、仕様が矛盾してて、現実的に実装できない可能性も有るのでは? これは当人も気づいてて言及してるが、実際に矛盾してるかどうかまでは分からないようだ。 > JS also ensures that /\w/iu is the inverse of /\W/iu. (https://github.com/kkos/oniguruma/issues/351#issuecomment-2818389363) 俺も考えてみたが、よく分からん。 単純には、[\w]!==[^\W]でどうにも実装できないケースがあれば、 どのみちいつか breaking change するしか無いので、後腐れなく出来るのだが。 ところで同様の問題は、多分「濁点」にもある。 (この板がunicode許可してるかは知らんので以下見た目意味不明になるかもだが) Unicodeには、結合文字用濁点(0x3099)があるので、「あ゙」とかも出来る。(表示系が対応してれば前の字と重ねて表示され、あに濁点がつく) よって、「が(0x304c)」と「が(0x304b,0x3099)」は見た目区別がつかない。 (0x304b,0x3099を表示するのに、通常は、単純にビットマップを重ねるわけではなく、0x304cのフォントが使用されるから) おそらくこの辺もonigurumaは対策されてるのではないかと思う。 正直、これはヒットしてくれたほうが助かるのは事実。 というかね、ブラウザ(Ctrl+F)ではヒットするが、JSではヒットしないので、 見た目表示されてるのにJSから検索すると存在せず、あれ?ってなったことがあった。 だから見た目、現行の動作は、「仕様的に正しい」。 これは本当に重要で、先日も言ったが、仕様を追加するのはいつでも楽勝だが、削除するのは基本的に無理なので、 おかしな仕様を追加した時点で将来的に詰むのが確約されるから、これは全力で回避しなければならない。 現行の動作は、確かに正しい。 問題は、その場合に異常に遅くなるケースがある、ということであって、 本来は、仕様変更ではなく、速度対策『だけ』で済ませるべき状況であり、実際に高速化すれば何も問題なくなるはず。 とはいえ高速化はもう出来ません、ということなのだろうが、果たしてそうなのか?とは思う。
64 名前:デフォルトの名無しさん mailto:sage [2025/05/08(木) 21:51:59.95 ID:MhxTwPG60.net] 例えば典型的な糞ッタレ正規表現、 > a.*b.*c.*d.*e // --- (a) についてだが、 > a.*+b.*+c.*+d.*+e // --- (b) は確かに一つの解だろう。しかしこれは、最速ではない。 人間がやるときを考えれば分かるが、 $len = strlen($str); // ---(c) $e = strrpos($str,'e'); // 最後のe $d = strrpos($str,'d',$e-$len); // eより前の最後のd $c = strrpos($str,'c',$d-$len); // dより前の最後のc $b = strrpos($str,'b',$c-$len); // cより前の最後のb $a = strpos($str,'a',$b-$len); // 最初のa if ($a<$b) // check と後ろから検索するのが速く、正規表現にすると /(?<=(a.*))(?<=b.*?)(?<=c.*?)(?<=d.*?)(?<=e(.*?))$/ --- (d) となる。が、まあ、(d)だと得られる結果が微妙に異なってしまうので後処理必要だが、(というより同じ結果を得られる正規表現を書けなかったorz) 内部的に自動的にこの方向で高速化してくれ、となる。 単純には、greedyに対してnon-greedyで右から検索すれば多分最速になる。 この辺、バックトラックの指定を事細かく出来る=走査順が仕様として規定されてしまう=左から右に走査、となってしまってるのが問題なので、 「任意の最適化の許可」フラグで、右から左に走査することも許可し、(勿論それ以外にもやっていい) 結果的にクソ速いがバックトラック制御は出来ませんよ、が正しい気がする。 (フラグ指定した場合、どう走査されるかはエンジン任せで、 結果的にバックトラック制御を指定してもどう動くか予想できず、実質使えなくなる。 が、問題は速度が遅いことであり、バックトラック制御をするのが目的ではないのでこれでいいはず)
65 名前:デフォルトの名無しさん mailto:sage [2025/05/08(木) 21:52:39.44 ID:MhxTwPG60.net] ちょっと伝わりにくいだろうからもう一度書いておくと、俺の希望としては、 プログラマがコードとして書くのは(a)で、 これを内部的に(c)で処理して最速化しろ、 処理順だけ書けば(d)になるが、この正規表現では読むのに時間がかかる(所要30秒)ので無理、 「匠」は(b)を書くが、これは(a)よりは理解に時間がかかる(所要10秒)し実行速度も最速ではない。 「プログラマ」は(a)で無理なら最速の(c)プログラムを書くが、 (a)は2秒で理解出来るのに対して、 (c)見て(a)と理解するには1分かかるので、前述のとおり、これをプログラム全域にまぶすと後々詰む。 最低限、(c)の先頭行に、// /a.*b.*c.*d.*e/ を高速化した とコメントがないと死ねる。 しかし結局、(a)の処理が速ければ最初から何も問題ないので、目指す仕様はここで、内部的に頑張ってくれ、という事。 ユーザーに「匠」となり、最適な正規表現を精巧に作り上げることを要求するのではなくてね。 (だから仕様追加するなら「後ろから検索」フラグ、でもいい。 そして /e.*?d.*?c.*?b.?a/Backwards で(a)と同様の結果が得られるとかでも)
66 名前:デフォルトの名無しさん mailto:sage [2025/05/08(木) 21:53:03.02 ID:MhxTwPG60.net] とにかく、ユーザーが困っているのは「仕様」ではなく「実行速度」なのだから、 それを「仕様」の限定化(仕様縮小=スペックダウン)で回避するのは悪手であり、まず高速化をやるのが先だ。 あるいは \U のように、unicode対策を外すフラグ付加(=フラグ付加時のみ仕様縮小での高速化)で対応できる。 kkos氏はこの仕様が実行速度に多大な影響を及ぼしているのを知っており、元々外したいと思ってたのだろうがね。 しかし、この状況で「仕様」を変更するのは、一般論としては明確な間違いだ。 何度も言ってるが、今の仕様は正しいので。 (とはいえ、結局この辺の采配、つまり理想と現実の兼ね合いでどう仕様を決めていくかが最終的な繁栄/衰退につながるので、 勿論kkos氏が決めるべきだし、実際、この仕様を捨てたら爆速化して更に支持率ダダ上がり、の可能性もある。 まあこの辺の采配を間違えたのがRubyと見てるが、onigurumaは果たしてどうなるか、といった所)