Movatterモバイル変換


[0]ホーム

URL:


BLOGTIMES

cles::blog

平常心是道
»ArchiveList (Tag for "regex" )
«Prev ||1 ·2 ·|Next»
2022/03/24

Python で正規表現の構文木を得るには

python  regex 

Python で正規表現を構文解析だけした結果(内部表現)を得る方法がないかと思って調べてみたところ、sre_parseを使えばできることが分かったのでメモ。

例えば、メールアドレスにマッチする正規表現^[a-zA-Z0-9_+-]+(.[a-zA-Z0-9_+-]+)*@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$)を parse すると[(AT, AT_BEGINNING), (MAX_REPEAT, (1, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 95), (LITERAL, 43), (LITERAL, 45)])])), (MAX_REPEAT, (0, MAXREPEAT, [(SUBPATTERN, (1, 0, 0, [(ANY, None), (MAX_REPEAT, (1, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 95), (LITERAL, 43), (LITERAL, 45)])]))]))])), (LITERAL, 64), (MAX_REPEAT, (1, MAXREPEAT, [(SUBPATTERN, (2, 0, 0, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57))]), (MAX_REPEAT, (0, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 45)])])), (MAX_REPEAT, (0, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57))])])), (LITERAL, 46)]))])), (MAX_REPEAT, (2, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90))])])), (AT, AT_END)] という表現を得ることができます。

この表現を sre_compile でコンパイルすると実際に正規表現として利用できるようになるようです。

$ pythonPython 3.9.10 (main, Feb 27 2022, 15:02:07)[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linuxType "help", "copyright", "credits" or "license" for more information.>>> import sre_parse>>> import sre_compile>>> sre = sre_parse.parse("^[a-zA-Z0-9_+-]+(.[a-zA-Z0-9_+-]+)*@([a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]*\.)+[a-zA-Z]{2,}$")>>> sre[(AT, AT_BEGINNING), (MAX_REPEAT, (1, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 95), (LITERAL, 43), (LITERAL, 45)])])), (MAX_REPEAT, (0, MAXREPEAT, [(SUBPATTERN, (1, 0, 0, [(ANY, None), (MAX_REPEAT, (1, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 95), (LITERAL, 43), (LITERAL, 45)])]))]))])), (LITERAL, 64), (MAX_REPEAT, (1, MAXREPEAT, [(SUBPATTERN, (2, 0, 0, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57))]), (MAX_REPEAT, (0, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57)), (LITERAL, 45)])])), (MAX_REPEAT, (0, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90)), (RANGE, (48, 57))])])), (LITERAL, 46)]))])), (MAX_REPEAT, (2, MAXREPEAT, [(IN, [(RANGE, (97, 122)), (RANGE, (65, 90))])])), (AT, AT_END)]>>> comlied = sre_compile.compile(sre)>>> comlied.match("hoge@example.com")<re.Match object; span=(0, 16), match='hoge@example.com'>>>> comlied.match("hoge..@example.com")>>>

これを上手く使えば正規表現同士を自動的に合成するようなライブラリを作ったりすることができそうです。


    at 23:13 |
    2021/06/06

    Regexp::Assemble を go で実装した rassemble-go が便利

    golang  regex 
    rassemble-go - Regexp::Assemble を go で実装した rassemble-go が便利

    複数の正規表現を1つにまとめてくれる「正規表現あせんぶるちゃん」がいつの間にか消えていて、手軽に導入できる代替を探してみたら go で実装されたrassemble-go というプロジェクトを見つけました。

    コマンドラインから簡単に導入できるので、自分で使っている環境にインストールしておくと便利です。


      at 22:26 |
      2020/05/08

      正規表現のデバッグには RegExr が便利

      regex  programming 
      RegExr - 正規表現のデバッグには RegExr が便利

      以前、正規表現をインタラクティブにデバッグできるRegex101 というオンラインのツールを取り上げましたが、もう一つRegExr というサイトを見つけました。

      オンラインで手軽に使えるだけでなく、GitHub でソースコードが配布されている*1ので、用途に合わせて改造したりすることが可能です。

      • *1: ライセンスは GPLv3

      at 16:38 |
      2017/07/30

      オンラインで正規表現をテストできる Regex101

      regex  programming 
      Regex101 - オンラインで正規表現をテストできる Regex101

      オンラインで正規表現をテストできる「Regex101」というサイトが便利だったのでメモ。

      画面はちょっとした IDE のようになっており、画面上部のRegular Expression の部分にテストしたい正規表現を入力し、その下のTest String の部分に検索対象となるテキストを入力すると、マッチした結果がハイライトで表示されるようになっています。正規表現のエンジンはPCRE や JavaScript など、代表的なものがサポートされており、画面左にあるメニューから切り替えができます。

      実際に試しながら試行錯誤できるので、プログラムの開発中に役立ちそうです。


        at 14:44 |
        2015/08/25

        Windows で grep したい

        windows  cli  regex 

        Windows のコマンドプロンプトで unix の grep のようなコマンドがあれば良いのに・・・と思って調べてみたら findstr というコマンドを見つけたのでメモ。
        いちおう正規表現にも対応しているようなので、外部ツールがインストールできない環境で活躍しそうです。

        試しに実行してみたら、こんな感じでした。

        C:\Windows\system32>dir | findstr dll2013/07/24 15:54 794,328 accesor.dll2014/10/29 11:00 3,814,400 accessibilitycpl.dll2013/08/22 20:45 39,424 ACCTRES.dll2014/10/29 11:43 10,240 acledit.dll2014/10/29 10:57 1,038,336 aclui.dll

          at 12:32 |
          2013/10/05

          JavaScript 版 Regexp::Assemble が便利

          javascript  regex  programming 
          正規表現あせんぶるちゃん デモ - JavaScript 版 Regexp::Assemble が便利

          複数の正規表現を最適化しながら1つにまとめてくれるRegexp::Assemble は、大きな正規表現を書きたいときにとても便利です。

          唯一の不満点は開発時に試行錯誤しながら正規表現を書いていきたいような場合に対話的に実行できないことだったので、上手いやり方がなにかないかと思って探してみたら、PHP 版の Regexp Assemble For PHP を元に JavaScript に移植したバージョンを見つけたのでメモ。

          デモサイトである正規表現あせんぶるちゃんを触ってみればわかりますが、実際の正規表現を文章に対して適用したときにどの部分がマッチ対象になるか一目瞭然なので、これでやりたいことはほぼ達成できそうです。埋め込み用の正規表現生成で一度きり正規表現が生成できれば OK という場合も気軽に使えてよさそうですね。


            at 22:03 |
            2013/10/03

            Ruby で正規表現がマッチした場所と文字列を取得する

            ruby  programming  regex 

            例えばfoobarbazfoobarbaz という文字列に対して/foo|baz/ という正規表現マッチさせると foo と bar が2箇所ずつ合計4箇所マッチするわけですが、マッチした文字列とポジションを一緒に取得をする方法が Ruby にはないようだったので書いてみたら意外と面倒だったので、忘れないようにメモ。

            ちょっとムダなことをしてるような気がしなくもないですが、一応できました。
            どちらも実行すると{0=>"foo", 6=>"baz", 9=>"foo", 15=>"baz"}という感じになります。

            for_1_9_or_later.rb

            require "enumerator"str = "foobarbazfoobarbaz"pat = /foo|baz/matches = str.enum_for(:scan, pat).with_object({}){|m, t| t[Regexp.last_match.begin(0)] = m }p matches

            1.8.5 だと with_object() が使えないので、こんな感じでしょうか。
            そこはかとなくダサイ感じですが、今日のところはこの辺で。

            for_1_8.rb

            require "enumerator"str = "foobarbazfoobarbaz"pat = /foo|baz/matches = {}str.enum_for(:scan, pat).each{|m| matches[Regexp.last_match.begin(0)] = m }p matches

              at 18:51 |
              2013/09/03

              Regexp::Assemble で正規表現を生成する

              perl  regex 
              詳説 正規表現 第3版

              以前、Regexp Assemble For PHP は使ったことがありましたがオリジナルのRegexp::Assemble は使ったことがなかったのでちょっと動かしてみました。
              このモジュールを使えば、フクロウ本とにらめっこしなくても、複雑な正規表現を効率よく組み立てることができます。

              サンプルほとんどそのままですが、UTF-8が通るようにしてあります。

              #!/usr/bin/env perluse Regexp::Assemble;use warnings;use strict;use utf8;binmode STDIN, ":utf8";binmode STDOUT, ":utf8";my $ra = Regexp::Assemble->new();while (my $line = <STDIN>){ chomp($line); $ra->add($line);}print $ra->re;

              以下、実行例。

              [Regexp::Assemble で正規表現を生成する の続きを読む]

                at 17:45 |
                2013/01/04

                正規表現を可視化するサービス

                javascript  regex  visualize 
                拡張子が .jpg かどうかを調べる正規表現 - 正規表現を可視化するサービス
                否定先読みを使って 00 以外の2桁の数値にマッチする正規表現 - 正規表現を可視化するサービス

                Regexperという正規表現を可視化するサービス紹介されていて*1便利そうだったのでメモ。

                例えばファイル名が .jpg/.jpeg で終わっているかを調べる正規表現(.*\.jpe?g$)を投入してみると、右の図のように可視化されました。

                これは簡単すぎるので、もうちょっと複雑な例を投入してみます。ここでは普段はあまり使わないような否定先読みを使ってある00 以外の2桁の数値にマッチする正規表現((?!00)\d{2}) にしてみます。このあたりになると、パット見で何をしているのか分からないかもしれませんが、こういうのを可視化するのには向いてそうです。

                あとは大学の講義等で、正規表現の解説なんかにもいいかもしれないですね。


                at 18:10 |
                2011/11/04

                Regexp Assemble For PHP

                php  regex 

                以前、Net::CIDR::LiteというIPアドレスの羅列からCIDR表現を生成するPerlのライブラリを紹介しましたが、今度はその正規表現版とも言うことが出来るphp向けライブラリが公開されていたのでメモ。
                これを使うと、複数の単語にマッチする最適化された正規表現を簡単に得ることが出来ます

                正規表現じぇねれーた

                改行区切りで単語を入れると、すべての単語にマッチする正規表現を自動的に作成します。
                perlにはRegexp::Assembleという正規表現を作成してくれるモジュールがあります。
                これを PHPに移植して、 Regexp Assemble For PHPなるモジュールを作って見ました。

                例えば、このサイトで使っているコメントのブラックリストの最適化をしてみます。これまで正規表現については単語を単純にOR(|)でつなげていたのですがこのライブラリを使うことでこのように変換することができました。今のところ特に問題はなさそうです。

                (anonymous|pharma|condylox|allegra|cum|tramadol|phentermine|addfreestats|cash|enlarge|loan|drug|hoodia|viagra|buy|pill|porn|cheap|casino|lacoste|ringtones|propecia|vibrator|acai|tylenol|codeine|generic|zoloft|tylenol|hydrocodone|percocet|dating|levitra|diet|zolpidem|dvd decrypter|singulair|valsartan|diovan|alprazolam|xanax|migraine|purchase|tablets|\.\.\.)
                (?:p(?:h(?:entermine|arma)|ercocet|ropecia|urchase|ill|orn)|a(?:(?:ddfreestat|nonymou)s|l(?:prazolam|legra)|cai)|d(?:(?:atin|ru)g|i(?:ovan|et)|vd decrypter)|c(?:o(?:ndylox|deine)|as(?:ino|h)|heap|um)|v(?:i(?:brator|agra)|alsartan)|t(?:(?:ramad|ylen)ol|ablets)|l(?:acoste|evitra|oan)|h(?:ydrocodone|oodia)|(?:migrain|enlarg)e|zol(?:pidem|oft)|ringtones|singulair|generic|\.\.\.|xanax|buy)

                なかなか面白いライブラリですね。
                需要ないかもしれませんが、これを使ってNP_BlackListを書き直したりするとちょっとは動作が速くなったりするかもしれません。


                  at 23:53 |
                  «Prev ||1 ·2 ·|Next»
                  »ArchiveList (Tag for "regex" )
                  Copyright © 2004-2023 by CLES All Rights Reserved.
                  サイト内検索
                  検索ワードランキング
                  貸金庫 審査
                  銀行で貸金庫を借りてみた
                  Photo
                  ポスチャーフィット部品検査着ポテトなど生レモン尽くしスカッシュ正常に受付が完了しました財産債務調書バレット食道2024 年度 基盤研究(C)(一般) blog.cles.jpCelestica Seastone DX010ポスチャーフィットの割れ母子健康手帳 省令様式アーロンチェアのワイヤー新型コロナワクチン接種証明書アプリ冥銭
                  へぇが多いエントリ
                  閲覧数が多いエントリ
                  1 .アーロンチェアのポスチャーフィットを修理(99673)
                  2 .年次の人間ドックへ(99086)
                  3 .福岡銀がデマの投稿者への刑事告訴を検討中(99076)
                  4 .三菱鉛筆がラミーを買収(98686)
                  5 .2023 年分の確定申告完了!(1つめ)(98655)
                  最新のエントリ
                  cles::blogについて
                  誰が書いてる?
                  最近行った場所
                  サイトポリシー
                  タグ一覧
                  検索ワードランキング

                  カテゴリ別エントリ
                  Referrers

                    Powered by CLES
                    Nucleus CMS v3.31SP3/w memcached
                    21375328(W:5953 Y:1545 T:1147)
                    cles::blogのはてなブックマーク数
                    benchmark


                    [8]ページ先頭

                    ©2009-2025 Movatter.jp