[{"data":1,"prerenderedAt":276},["ShallowReactive",2],{"project-35053328":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":28,"sentiment":29,"stance_mix":30,"scored_comments":34,"aspects":35,"strip":39,"post_text":41,"what":42,"said":66,"maker_in_thread":137,"shape":145,"grid":150,"attempts":237,"same_week":238,"maker_shows":181,"maker_hidden":268,"reader_version":269,"card":270},"35053328","Brzozowski","Regex Derivatives (Brzozowski Derivatives)","title","Show HN: Regex Derivatives (Brzozowski Derivatives)","https:\u002F\u002Fgithub.com\u002Fc0stya\u002Fbrzozowski","github.com","c0nstantine",1678180899,2023,103,35,624,3109,21,"notable","languages","regex engine","library",[24,25,26,27],"regex","brzozowski derivatives","regular expressions","dfa","mixed",-0.176,{"positive":31,"neutral":32,"mixed":33,"critical":32},1,3,0,7,{"performance":36,"idea":37,"docs":38},{"positive":33,"critical":32},{"positive":31,"critical":33},{"positive":33,"critical":33},[31,33,33,33,33,33,33,40,31,32,33,33,33,33,33,32,33,33,32,33,31,33,33,33,33,33,33,33,33,33,33,33,33,33,33],5,"A Python sketch of a regex engine in less than 150 lines of code",{"problem":43,"audience":53,"pricing":53,"motivation":54,"time_to_build":53,"stack":58,"openness":64,"stage":65,"team_size":65},{"value":44,"source":45,"evidence":46},"Illustrates regex matching via Brzozowski derivatives in a minimal form","maker",[47,50],{"id":48,"by":11,"text":49},"35055468","I agree. There is no magic. DFA construction has a risk of exponential growth in the number of states. My point was to illustrate the technique. I found no minimalistic python…",{"id":51,"by":11,"text":52},"35056931","I think I got your point. It is valid. To construct the DFA and have a finite number of derivatives we have to keep track of the following equivalences: r + r ~ r r + s ~ s + r…",null,{"value":55,"source":45,"evidence":56},"Demonstrate the technique; found no minimalistic Python implementations",[57],{"id":48,"by":11,"text":49},[59],{"value":60,"source":45,"evidence":61},"Python",[62],{"id":63},"post","open_source","unknown",{"praise":67,"objections":76,"requests":89,"questions":94,"alternatives":106},[68],{"value":69,"source":70,"evidence":71},"Concept is cool and the code is a good illustration","commenter",[72],{"id":73,"by":74,"text":75},"35056667","H8crilA","This comment is not following HN guidelines, but: I saw this and I was immediately sure that I could make this blow up exponentially. But then I got too lazy to think about…",[77,84],{"value":78,"source":70,"evidence":79},"Naive matching can blow up exponentially, e.g. (A*)* against long input",[80],{"id":81,"by":82,"text":83},"35054792","mananaysiempre","From my own experiments[1], I suspect your engine might still be prone to exponential blowup: you only get proper linear matching if you reassociate and sort the choice…",{"value":85,"source":70,"evidence":86},"Linear matching needs reassociation, sorting and merging of terms",[87,88],{"id":81,"by":82,"text":83},{"id":51,"by":11,"text":52},[90],{"value":91,"source":70,"evidence":92},"Add DFA construction and term equivalence reduction",[93],{"id":51,"by":11,"text":52},[95],{"value":96,"source":70,"evidence":97},"How does derivative matching handle large Unicode character classes?",[98,102],{"id":99,"by":100,"text":101},"35055222","burntsushi","As the sibling commenter said, indeed, the regex crate does not use derivatives. If you wouldn't mind, could you share what led you to that conclusion? I'd love to fix it! I am…",{"id":103,"by":104,"text":105},"35056457","def-lkb","I don't think you should be worried about Unicode in particular. Although the derivation formula on paper is parameterized by a character, you don't have to compute the…",[107,114,120,127],{"value":108,"source":70,"evidence":109},"ocaml-re",[110],{"id":111,"by":112,"text":113},"35055667","Drup","ocaml-re[1] uses a derivative-style construction to lazily build a DFA. The general idea is to use something similar to Owens et al's DFA construction, but doing it inline with…",{"value":115,"source":70,"evidence":116},"redgrep",[117],{"id":118,"by":11,"text":119},"35055238","I don't think Rust regex engine relies on this technique. I guess the main point is when you construct the DFA directly you still have the possibility of the exponential…",{"value":121,"source":70,"evidence":122},"Rust regex crate",[123],{"id":124,"by":125,"text":126},"35054970","SomeoneOnTheWeb","IIRC, that's what the Rust regex engine[1] currently uses [1] https:\u002F\u002Fgithub.com\u002Frust-lang\u002Fregex",{"value":128,"source":70,"evidence":129},"Agda and Coq formalizations",[130,134],{"id":131,"by":132,"text":133},"35055338","evolveyourmind","And here the formalized proof in less than 150 lines of code (in Agda) for Brzozowski Derivatives for regex matching (and additional regular languages theorems):…",{"id":135,"by":11,"text":136},"35055837","Thanks for sharing. I am not familiar with Agda. Will take a look. There is somewhat similar code in COQ: https:\u002F\u002Fgithub.com\u002Fcoq-community\u002Fregexp-Brzozowski",{"comments":138,"answered":33,"key":139},6,[140,141,142],{"id":48,"text":49},{"id":51,"text":52},{"id":143,"text":144},"35064968","Hi, thanks for sharing. Didn't know there is a python implementation. Your article is broader and I like the functional flavor. For the 'compaction' you mention, yes it is…",{"commenters":146,"max_depth":147,"maker_replies":138,"first_comment_mins":148,"lifespan_hours":149},16,9,206,18,[151,153,155,158,159,161,165,167,169,172,174,176,179,183,185,189,192,195,199,201,204,205,207,209,211,213,214,217,220,222,224,228,230,232,235],[81,33,31,152,82,33],"project\u002Fcritical\u002Fperformance",[48,33,33,154,11,31],"maker\u002Fneutral\u002Fidea",[156,33,33,157,82,33],"35055663","commenter\u002Fneutral\u002Fperformance",[51,33,33,154,11,31],[160,33,33,157,82,33],"35057534",[162,33,33,163,164,33],"35059374","other\u002Fneutral\u002Fdocs","carapace",[143,33,33,166,11,31],"maker\u002Fneutral\u002Fnone",[73,33,40,168,74,33],"project\u002Fpositive\u002Fidea",[170,33,31,152,171,33],"35059560","djoldman",[131,31,32,173,132,33],"project\u002Fneutral\u002Fdocs",[135,31,33,175,11,31],"other\u002Fneutral\u002Fnone",[177,31,33,175,178,33],"35058243","DonaldPShimoda",[180,181,33,163,182,33],"35056180",2,"noelwelsh",[184,32,33,163,171,33],"35059571",[186,187,33,175,188,33],"35057765",4,"aarchi",[190,40,32,173,191,33],"35054699","enricozb",[193,40,33,194,11,31],"35055082","maker\u002Fneutral\u002Fdocs",[196,138,33,197,198,33],"35058460","other\u002Fneutral\u002Fidea","DonHopkins",[124,34,32,200,125,33],"project\u002Fneutral\u002Fidea",[202,34,33,203,82,33],"35055073","commenter\u002Fcritical\u002Fperformance",[99,34,31,152,100,33],[111,34,33,206,112,33],"other\u002Fneutral\u002Fperformance",[208,34,33,175,100,33],"35055991",[210,34,33,175,112,33],"35056099",[212,34,33,175,100,33],"35056173",[103,34,33,157,104,33],[215,34,33,216,100,33],"35056639","commenter\u002Fneutral\u002Fnone",[218,34,33,219,104,33],"35057134","commenter\u002Fneutral\u002Fidea",[221,34,33,157,100,33],"35057241",[223,34,33,219,104,33],"35058215",[225,34,33,226,227,33],"35058237","commenter\u002Fpositive\u002Fidea","osaariki",[229,34,33,219,100,33],"35058447",[231,34,33,226,227,33],"35059706",[233,34,33,234,100,33],"35059861","commenter\u002Fpositive\u002Fnone",[118,34,33,236,11,31],"commenter\u002Fcritical\u002Fidea",[],[239,244,249,254,258,263],{"id":240,"name":241,"points":242,"category":243},"35073603","Braggoscope",688,"learning_science",{"id":245,"name":246,"points":247,"category":248},"35032506","Lander",564,"games",{"id":250,"name":251,"points":252,"category":253},"35026902","Llama-dl",343,"ai",{"id":255,"name":256,"points":257,"category":20},"35055308","NESFab",298,{"id":259,"name":260,"points":261,"category":262},"35042316","UJRPC",290,"infrastructure",{"id":264,"name":265,"points":266,"category":267},"34999774","Mathesar",281,"data",false,"v2",{"id":271,"name":5,"line":6,"ai":268,"cat":20,"year":13,"points":14,"comments":15,"rec":28,"s":272,"top":18,"kw":273,"maker":11,"domain":10,"tier":19,"attempts":33,"strip":274,"url":9,"mix":275,"praise":69,"objection":78,"sub":21},35053328,-0.18,[24,25,26,27],"10000005130000030030100000000000000",[31,32,33,32],1793991061535]