[過去ログ] Regular Expression(正規表現) Part14 [無断転載禁止]©2ch.net (1002レス)
前次1-
抽出解除 必死チェッカー(本家) (べ) 自ID レス栞 あぼーん

このスレッドは過去ログ倉庫に格納されています。
次スレ検索 歴削→次スレ 栞削→次スレ 過去ログメニュー
リロード規制です。10分ほどで解除するので、他のブラウザへ避難してください。
889
(1): 2019/07/17(水)08:28 ID:2/Bgill9(1/5) AAS
>>873訂正
俺は俺のケースだけ考えていたが、これだと871内URLの筆者のケースと合致しない。
そこで一応、両方とも合致する実装を考えてみた。
(といってもバグってる実装について推測すること自体はあまり意味がないが)

Perlはおそらく、^のフラグではなくて、空文字マッチ後のそのマッチ区間の*を+にしてる。
(というより筆者もそう言っているのだが俺が早とちりしてしまった)
871のケースだと、正規表現 (?:^|>)(.*?)(?:$|<) に対して、
1回目:(?:^|>)(.*?)(?:$|<)
2回目:(?:^|>)(.+?)(?:$|<)
というわけだ。結果、2回目は「先頭、<含んだ1文字、次の<まで、となり、
その筆者の説明通り先頭タグを含んで次タグ或いは文末まで伸びることになる。

俺のケースでは、正規表現 (^|[@;])[^@;]* に対して、
1回目:(^|[@;])[^@;]*
2回目:(^|[@;])[^@;]+
だから '@time;prop1:style1;prop2:style2' に対して @time のマッチも正しく取れることになる。

こういった場合、実装者は安全側に倒したくなる物だが、
現実は安全側に倒しすぎて余分なケースを含んでしまい、結果、バグっているというわけだ。
JavaScriptは最高に安全な実装、「空文字マッチは1文字進める」とした。(おそらくRubyその他もそう)
これだと絶対に無限ループはしないが、俺のケースでバグる。
Perlの実装だと俺のケースは通るが、871内URLの筆者のケースでバグる。
その他バグケースも出してくれれば俺の推測で合っているかどうかは答える。
890: 2019/07/17(水)08:28 ID:2/Bgill9(2/5) AAS
正しい実装は、「経路全体」(つまりツリーのリーフ)に対してフラグを持たないといけない。
Perlは「区間」(=経路の一部)に対してフラグをつけてしまったところが間違いだ。
871のケース、単純化する為に (A0|A1)B(C0|C1)として、
1回目:A0BC1 で空文字マッチ
そして空文字マッチの場合はこれを記録し、これと同一の場合は次回以降はスキップする。
結果、2回目:最初に A0BC1 がマッチするがこれは捨てられ、次に A1BC0またはA1BC1となる。
そして非空文字マッチとなったので、この記録を全破棄して、同様にループを繰り返せばいい。

実装の修正は、探索関数そのものにだいぶ手を入れないといけないのでそれなりに大変だ。
まずは全部の最終段に「最終チェック」を入れて上記リストと照合、記載有ればマッチ失敗として探索継続、としなければならないが、
おそらくこれが1ヶ所では済まない。
ただしこれはリターンパスを辿ればいいので何らかのツールが有ればほぼ自動でいけるかもしれない。
次に上記リストを作成する為に全経路を出力させなければならない。
デバッグ用にこれが既にあればラッキーだが、なければ自前で作らなければいけない。
といっても内容はツリーのノードを辿るだけなので、ツリーのフォーマットが分かればすぐだが、
ゴリゴリに高速化とかしていると割と意味不明なコードになっていることが多いので、
その状態で確認するのは結構辛いとは思う。
リストの管理は、空文字マッチなら追記、非空文字マッチならクリア、なので、これはやるだけだ。
リストの管理も探索関数にやらせて、探索関数は
今:マッチ場所とマッチ長さを返す
修正後:マッチ場所とマッチ長さを含んだ『配列』を返す、とし、
「空文字マッチの場合は自動で継続、非空文字マッチまたは終了まで探索、まとめて配列で結果を返す」とするのがいいだろう。
891: 2019/07/17(水)08:29 ID:2/Bgill9(3/5) AAS
なおPerlの実装だと『上位関数のみ』で対策できるため、
「取り敢えず1時間で直せ」と言われたらこうなるのも分からなくはない。
しかしいまだにそのままだというのは怠慢でしかないが。
JavaScript等も同様、『上位関数のみ』で対策出来るところで留まっている点からも、これは言える。
しかし現時点で世界中のプログラマがどれだけ無駄な時間を消費することになっているのかを考えれば、
こんなのは手間であろうがさっさと直せ、でしかないが。

いずれにしても、俺が修正してやる、修正案はこれだ!と具体的に出してくるのならレビューはする。
我こそは!という奴は頑張れ。
899
(1): 2019/07/17(水)20:30 ID:2/Bgill9(4/5) AAS
>>894
ないね。
聞いたこと無いし、JavaScriptで試した限り ([@;]|^)[^@;]* でも結果は同じだった。
ただ、確かに普通に考えたら左優先でいいし、上記入れ替えで @time をキャプチャ出来るようになるべきではある。
言われてみれば優先順位が決まってないことに驚きだ。
901: 2019/07/17(水)20:40 ID:2/Bgill9(5/5) AAS
>>895
お前は毎回Rubyの話をどのスレにも持ち込んでいる荒らしだろ。
何か言いたいことがあるのなら必ず結論を書け。
何が言いたいのか分からないのでウザイ。だから荒らしなんだよ。

+ に変えて空文字マッチをなくし、結果、希望の文字列を得る、という運用で回避するのはありだ。
ただ、その場合は、プログラマにそう分かるように、
「Rubyの正規表現エンジンは空文字マッチ周りにバグがあるので、注意してください。
空文字マッチがある正規表現を与えた場合、予期せぬ動作になることがあります。」とアナウンスしないといけない。
事実上空文字マッチが使えないが、事実なんだからそうするしかないだろ。
Rubyはこういう事を全くしないからゴミなんだよ。Rubyは滅ぶべくして滅んで行ってるだけ。
JavaScriptは少なくとも仕様に明記はしてる。
ただそれだと弱いからMDNにも書け、というのが俺の主張であり、JavaScriptスレに勝手に依頼しておいた。
以前RegExp.testの件で同様に依頼したら追記されたから、そうなるのを願っている。
そういう、「落とし穴」は共同して塞いでいかないと駄目なんだよ。

完璧な言語なんてない。だから多少バグがあるのは仕方ないとして、
それを未来永劫新規プログラマに押しつけて「キャハハー、お前も落ちたか!」なんてやっているようでは駄目なんだ。
Rubyはプログラマに対してリスペクトが全くない。だから廃れるし、俺もそうなることを願っている。
お前はRubyを吹聴しさえすれば布教出来ると勘違いしているようだが、そんなことはない。
当たり前だが新人にとってはこんなバグにつき合わされること自体大迷惑でしかないんだよ。
今回のでもPCREが一番ましだし、Rubyなんて選ばれる理由がないだろ。
ゴミだと分かっているものを広めるのは、単なる詐欺師でしかないぞ。
お前はお前の行為によってRubyへの反感を得ているだけなことを自覚した方がいい。
あちこちのスレでお前は相当ウザがられてる。

そういうのではなくて、バグを修正するとか、仕様書に明記するとか、
何でそういう建設的な方向に努力出来ないんだ?
こういう地道な積み重ねを全くやってないからRubyの現状はあるわけでさ。
前次1-
スレ情報 赤レス抽出 画像レス抽出 歴の未読スレ AAサムネイル

ぬこの手 ぬこTOP 0.050s