1. 雨宿りとWEBの小噺.fm
  2. Season 3-85.「土日で正規表..
2024-02-02 14:17

Season 3-85.「土日で正規表現と格闘した話」

はい❗第359回は,タイトル通り正規表現と久しぶりに格闘したときのお話をしました💁


ではでは(=゚ω゚)ノ


ーーーーー

🔗 LINKS

開発日誌 2024/01/28

https://kkeeth.github.io/my-development-log/DEVELOPMENT/2024/JAN/0128.html


♫ BGM

騒音のない世界「ワンルームの自由」

https://soundcloud.com/baron1_3/oneroom

See Privacy Policy at https://art19.com/privacy and California Privacy Notice at https://art19.com/privacy#do-not-sell-my-info.

00:08
はい、みなさんこんにちは。kkeethことくわはらです。本日もやっていきましょう。
kkeethのエンジニア雑談チャンネル。この番組では、ウェブ業界やエンジニアリング、いろんな技術についての情報を、雑談形式で発信していきたいと思います。
で、今日はこの土日でひたすら正規表現と戦った話ですね。
他にやらなきゃいけないことはあったんですけど、やっぱりプログラミング始めてしまうと、ついついそれに引っ張られてしまったってのもあるし、正規表現はやっぱり沼だなと思ったので、その辺の話をしようかなと思ってます。
で、結論から言うと、正規表現、結局やりたいことはできなかったんですね。
なんかデータの構造であったりとか、対象の文字列とかっていうところが複雑度が高くてですね。
一発正規表現できなかった。やりたかったのは、VSコード上で試観もできるんですけど、VSコードは優秀なので、検索するとき、正規表現としての文字列を指定して検索もできるんですね。
で、要はそこでヒットしたものを特定の文字列で一発時間できたらいいなっていうことをやりたかったんですね。
対象のデータはJSONデータなんですけど、厳密に言うとJSONではなくて中身ただの配列なんですけど。
配列の中にいろんなオブジェクトがふわっと含まれていて、一つのオブジェクトが中身は変わるんですけど、フォーマットは大体一緒のオブジェクトが配列でふわっと書かれていると。
で、その中の特定のキー2つピックアップして、そこの値を指定の文字列でバーンと時間をしたかったという感じです。
で、それがしたかったんですけど、結論的に言うと、配列なので、読み込んでJavaScriptでループぶん回して特定のキーのときに指定するっていう処理を書いてしまえば、ぶっちゃけるとJavaScript6、7行で終わっちゃうんですよね。
終わっちゃうんですけど、わざわざスクリプトに書いて、で、ファイル読み込みをしてみたいなことをするのがちょっとだるかったんです。
ファイル読み込みもせずに直接、もともとのJSONファイルをJSファイルに書き換えて、その配列を変数にぶち込んでしまえば一発でいけるんで、そこは問題ないんですけど。
今回はできればエディター上でやりたかった。で、やろうとしたんですね。
結果はできなくて、詰んだんですね。
どういう聖教言を流していたかとか、書いたかっていう履歴を見てるんですけど、まあ面白いですね。
久しぶりに聖教言と戦ったんですけど、まあ忘れまくってました。
例えばバックスラッシュの小文字のSってなんだっけっていうと、空白文字ですね。
まあいろんな空白文字がこの世界にもあるんですけど、っていうのを一括した空白文字を表すのがバックスラッシュSで、ラージのSはそういうものを全部除いた任意の文字列と。
あとなんて空白と開業とかを含まない任意の文字列としてドットがあるとかの感じですね。
今まで脳死でドットアスターみたいなことをやってたんですけど、そもそもドットアスターって何意味してたっけっていうのを忘れてやってたんで、
まあなんか適当に文字列を0個以上取ってきてくれるだろうと勝手に思ってたんですけど、いやそうではなかったなっていう感じですね。
とにかく全部の文字列を取ってきたかったっていうので、ドットとバックスラッシュLとバックスラッシュラージSとかとかやると、基本的には全部取ってくれる感じですね。
03:08
あと空白も欲しいからバックスラッシュの小文字のSも含めたりするとか。
それを仮括弧で括ってアスターにすると、もう全ての文字列の0個以上が取れるみたいなことをやって、そういえばこんな感じだったみたいなのを書いたんですけど。
本来やりたかったのは正規表現の配列の中ですね。
全部の配列の要素の中から特定のキーのものをピックアップしてっていうところなので、最初はそのキーの文字列をそのまま指定してあげて、
オブジェクトになっているので、コロンのスペースの並括弧の開きの方ですね、オープンの方の並括弧っていうのを指定をして、そこから適当な文字列、会議を含む列をばーっと選択をして、
で、閉じる。閉じるの方の並括弧。で、書けばいいじゃん。
普通に思ったんですけど、でもよく考えたらこれ配列なので、一つの要素の中が一個一個オブジェクトなんですけど、
その要素の中にキーが一個ある。それも別にいいんですけど、複数個ばーっと同じキーのものが見つかっちゃうんですよね。
要素一個目の特定のキー、ほげみたいなやつからスタートして、要素の一番末端の方のほげでまたヒットしてしまうみたいなところで、
その一つのでっかい選択肢になっちゃうっていうのがずっと悩ましくてですね、どうしようかなって思ったんですけど、
やろうとしたのは、最初にほげっていうキーをピックアップするのは全然余裕なんですよ。
で、ほげの次に確実に来るキーがフガだったとしましょう。
なので、ほげとフガで挟んであげて、で、それを中の文字列をごにょればいけそうだなっていうのもやったんですね。
で、やったことは工程後読みですね。工程後読みからピックアップをして、要はそのテストした文字列に引っかかったら、
ヒットしたらそれ以降の文字列に対して処理をしてくださいっていうので、先に工程後読みを書いておいて、
で、工程後読みってあれですね。かっこのクエスチョン、ダイナリーイコールみたいな書き方ですね。
で、それ以降でヒットする条件を指定してあげて、で、それにヒットすればその後の文字列でっていう書き方をして、
で、工程後読みでスタートの文字列を指定するじゃないですか。ほげっていうのを指定してあげて、
で、後の後ろの方ですね、末端の方は工程先読みですね。っていうのをやっておける。
いうような書き方をしました。
で、別にそんなことはしてなくて、普通にほげっていうキーとフガっていうキーで挟んであげてもいいじゃんっていう感じはあったんですけど、
まあぶっちゃけ両方やって両方うまくいかんかったんですよ。
で、原因としてはさっきと同じものです。
要素の一発目のほげって引っかかったんですけど、フガで引っ掛けようとしたら要素の末端のフガに引っかかってしまったので、
あ、これ無理じゃんってなったんですよね。
で、それをうまいこと要素の中だけで閉じて、で、それを書く要素分ザーッと引っかかるように正規表現できないかなっていろいろ格闘したんですが、
まあ結果無理で、なかなか難しいですね。
要素の1回以上とかって指定はもちろんできるんですよね。
正規表現ってナミカッコをして中に数字を指定してあげれば、もうその回数分って指定できたりします。
ナミカッコで数字カンマとかをつけると何回以上みたいな書き方もいい。
それもできなくはないんでやったんですけどね、なかなかこれがうまくいかなくて済んだんですよね。
06:01
で、正規表現って絶対的にそうか分からないし、僕が書いたのはNode.jsの環境なのでNode.js上の正規表現でしかないんですけど、
Perlとかだったらもう少しなんか違った書き方できたかも分からないですね。
なんですけど、JSOでやった環境では、なるべく長くヒットする。
多くヒットするように基本的な設計質はなってた気がします。
なので、個人的には一番小さいヒットをして欲しかったんですけど、
細かい設定とかは僕はちょっと分かってなかったのでしてなかった。
からか分からないですけど、なるべく大きいヒットをしようとするので、
その末端の要素と1個目の要素の間で挟んでしまったっていうような条件になったんですよね。
一番最初に見つかるところでもうそのまま検索止めて欲しかったんですけど、
両方引っかかるんですよね。要素の中だけのオブジェクトで閉じることもできるんですけど、
全体的にもヒットはするので、その差をうまいこと埋めることができなくて悔しく、
JavaScriptで結局スクリプトを書いたっていう感じです。
本当ここがなんかできたらいいなと思ったんですけど、
ちなみにどんな環境を書いたかっていうのは僕の開発日誌にも公開してるので、
後でどんな感じだったかっていうのは載せておきます。
開発日誌の中にもどんな配列の中からこのキーとこのキーの文字列でチカンをするみたいなことを書いてますので、
興味ある人は後でご自身でもチャレンジしてみてください。
なんか悔しいし、できたらそこを教えてほしいなと思います。
僕は最終的に配列.mapメソッドでガチャってやっちゃいました。
もちろんさっき言った通りで全体に引っかかってしまうんですけど、
一つの要素の中のオブジェクトだけだったらもちろんうまくいきました。
要はそれを全体にチカンしてしまうところが難しかったって感じですね。
やってみた感想としてはやはり正規表現で、
もうこれ一つだけでプログラミング言語感めちゃくちゃあるなと思いました。
でパッと昨晩書いてて今朝起きて読んでるんですけど、
自分で書いたからってのもちろんあるんですけど、
正規表現で勉強しますとちゃんと読めるなと思いましたね。
他人の正規表現読みづらと思いますけど、
勉強し直すとやっぱり読めるっていうのが面白かったですね。
これ読めるようになったり書けるようになったりしたら、
いろんなアルゴリズムでガチャガチャやってたものって
正規表現で一発でできるじゃんっていうのはやっぱり感じてしまいましたね。
今までのソースコードで、
自分が手続き的にガチャガチャ書いたものを正規表現一発で書けば、
この辺コード圧縮できたりするし、
複雑処理をしているところなので、
理解するのがそんなにメリットにならないんだったら、
正規表現に置き換えてしまっても良い気はします。
ただ正規表現って過読性最悪なので、
ちゃんとどういう思想、意図で正規表現を書いたかっていうのを書かないと、
他のチーム開発ではやっぱりしんどいし、
むしろチーム開発では正規表現をなるべく使わないというか、
シンプルなものだけを正規表現するぐらいがちょうどいいと思ったりしましたね。
この前僕がプログラミングの筋トレでやった、
09:00
数字を3桁区切りでカンマ区切りつけるみたいなやつですね。
あれも正規表現で一応できるはずなので、
それでやりたい方はどうぞって感じですけど、
あれぐらいちっちゃくしないと正規表現は本当に過読性悪くて、
何やってんねんで良くなるので、
チームではなるべくやらない方がいいし、
個人開発でもやるんだったら、
ちゃんとコメントで思想を書いてくださいねっていうのはすごくあると思います。
今やったりすると読めるようになるっていう体験の面白さ、
アハ体験に近い感はあるんですけど、
チュラデータさんのエンジニアさんの一人が、
基本情報処理試験受かったっていう話をブログを書いてて、
その中で言ってたのは、
見える世界が変わったみたいな書き方をされてたんですね。
今まで話聞いても全然話が分かんなかったりとか、
今まで知識がなかったので、
同じエンジニア同士でやってる話が自分の中では全然理解ができなくて、
ついていけなかったっていうのが理解できるようになったり、
今まで読めなかった技術ブログが知識を身につけたところで、
読める、読めるぞ!みたいなブログを書いてて、
その体験ってすごく大事なんだよなって思いましたし、
技術書が読めるようになってるので、
めちゃくちゃ今技術書を買いまくって、読みまくってるって話も見てて、
エンジニアのスタートって楽しいよなっていうのがあるので、
基本情報処理試験、やっぱバカにならんなってすくうく感じました。
あの体験っていうのは別に基本情報だけじゃなくて、
全部の分野に当てはまるもので、
それと似た体験を僕もこの土日にしたんだよなって感じです。
正規表現、今まで何度も書いたことはあるんですけど、
本気でちゃんと学んだっていう機会は実はそうそうなくて、
正規表現だけと戦ったのもまあ久しぶりだったので、
まあ面白かったなと思います。
で、さっき言った工程先読み、工程後読み、
これの逆版、否定先読み、否定後読みもあったりします。
ちょっと複雑な正規表現を書くときはこれを使ったりすると思いますけど、
これがですね、慣れてしまえばこんなもんだって感じなので使いこなせるんですけど、
正規表現は便利すぎるので、
かつ、なるべく長く大きくヒットするようにデフォルトで検索しようとするんですよ。
なのでちゃんと書かないと、
正規表現っていわゆる計算量爆発とか、計算回数爆発?
計算時間が、計算時間爆発もしくは計算量爆発とか言ったりする言葉があるんですけど、
超大な時間かかってしまって、
もしくはもうそのままエディターとかがバッファーオーバーフロー的に死ぬみたいなことがあったりするんですよね。
で、そういう落とし穴があるので、
まあ用法要領を本当に気をつけてくださいっていう感じです。
単なる数字の羅列からちょこっとやりたいことがある、
何かを抽出するみたいなのがあるんですけど、
その条件に当てはまることをなるべく多く、
かつなるべく長くヒットするように正規表現は動いてしまうので、
縛りをなるべくつけたまま、
つけてつけて縛って検索をしないとえぐいことになるよっていうような話ですね。
これでもこの概念とか考え方はMySQLとかSQLにもあるなと思います。
脳死でセレクトアスターとかしますけど、
アスターではなくてちゃんと最初から絞ってあげる。
セレクトなんちゃらをっていう絡む目をしっかり指定してあげるとか、
先に上訳から書くとこも結構大事ですよね。
上訳書き忘れて一発叩いてしまってめっちゃ膨大なデータ持ってきて
12:02
うわーってなることもよくあったりするので。
クエリログ出してしまえばその辺は見れたりするし、
エクスプレイに叩いてちゃんと実行計画見ればいいだけなんですけど、
最初やりがちなのでちゃんと上訳から書くのを癖にするのも一ついいなとの次第です。
それを正規上下の同じようにこれ爆発するかなみたいな書き方とか、
そういう記述法ってあるので、
それはいろんな方がブログにも書かれてますので、
その辺に説明はお任せしますけど、見ていただければというところですね。
便利な分、穴はあるし、
銀の弾丸的に素晴らしいツールってものはないよってことなので、
正規上下使う場合もその辺は気をつけていったらいいんじゃないかというところも改めて感じました。
今回この土日年は僕もVSコード上で何度もやったんですけど、
何度もVSコードの検索が終わらなくて、
エディターですね、VSコードそのものを
何回?6回か7回くらい開き直しましたね。
あ、これ死んだわっつって。
帰ってこなくなったんですよ、処理が。
なので無理やりアクティビティモニターらへんから強制終了したって感じですね。
プロセスそのままIDを指定して切るってのも良かったんですけど、
その辺はMacは最近うまいこと、
途中であ、こいつ死んだよって教えてくれたりするので、
それで切ってました。
まあ面白かったですね。やっぱり正規上下って楽しいっすわ。
てかプログラミングがやはり楽しいなって思ったんですけど、
やりたいことは単純に文字列の時間だったので、
正規表現がやりたいわけではなかった。
ので途中で諦めてさっさとスクリプトに書き換えれば良かったと思うし、
それだけであればこの土日ずっと使わず、
1時間ぐらいやってはもう無理だなって、
早く損切りするってのも一つ良かったんですけど、
今回は別に仕事じゃなかったし、僕が学びたかったので、
延々と時間を溶かしてしまったって感じですね。
こういう体験はエンジニアであるあるだと思うので、
あれですけど、
改めまして重複になりますけど、
もしチャレンジしたい方は後で僕の開発にしてやったことを共有しますので、
0.1.2.8ですね。
分公開しますので、見てみてください。
というところで、
正規表現楽しかったけど、
落とし穴もあるし大変だよっていう話ですね。
以上。
今回はこんなところで終わっていきたいと思います。
いつも聞いてくださり本当にありがとうございます。
ではまた次回の収録でお会いしましょう。
バイバイ。
14:17

コメント

スクロール