• ベストアンサー

正規表現でのパイプ(or)を減らしたいのですが

いつもお世話になっています。 正規表現のパイプ(|)は非常に遅くなるらしいので、[]内に並べるようにプログラムを修正しようと思っています。それで、 /a|b|c/ ---> [abc] のような方法は、よく紹介されているのですが、a,b,cが単独文字ではなく、単語になっているような場合、 /abc|def|ghi/ ---> [(abc)(def)(ghi)] だと多分ダメですよね(今実行環境が無く確認できません)。 それで、各々の単語を $a = 'abc'; $d = 'def'; $g = 'ghi'; のようにあらかじめ定義しておいて、 /$a|$d|$g/ ---> [$a$d$g] というように書き換えると、うまくいくのでしょうか? やり方が間違っていましたら、ご指摘いただきたく、よろしくお願いします。

  • aneja
  • お礼率93% (379/405)
  • Perl
  • 回答数2
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.2

ブラケットの中は独立したキャラクタとして扱われるので文字列をそこに収めることはできません。 #これは#1の方の回答にもあるとおり そんなに気になるのなら Regexp::Optimizer - optimizes regular expressions - search.cpan.org http://search.cpan.org/~dankogai/Regexp-Optimizer-0.15/lib/Regexp/Optimizer.pm このモジュールを使ってみるとか。 正規表現のマッチングを遅くする原因は色々あるので、 本当にその辺を知りたければ oreilly.co.jp -- Online Catalog: 詳説 正規表現 第2版 http://www.oreilly.co.jp/books/4873111307/ を頑張って読破しましょう。

aneja
質問者

お礼

早速のご回答、どうもありがとうございました。 やっぱり文字列はできないんですね。質問のような書き換えができないのなら、教えて下さったような最適化モジュールも検討してみます。

その他の回答 (1)

noname#39970
noname#39970
回答No.1

例えうまく行っても 結局文字列を展開し正規表現検索にかかるので変らない。 それどころか展開する分だけ遅くなる 実際は うまくいかない。 []は1文字でしか定義できないから。 orでダメなら複数回実行しかないと思う。 (速度的には判らないけれど複数実行の方が早い事もある。場合による)

aneja
質問者

お礼

早速のご回答ありがとうござました。やっぱりできないんですね。複数回実行もあわせて検討してみます。

関連するQ&A

  • 「マッチしない」正規表現の書き方

    正規表現について、おたずねします。 文字列 abc,def,ghi のいずれかにマッチする正規表現は (abc|def|ghi) ですよね。 それでは、「abc,def,ghi のいずれにもマッチしない」正規表現は、どう書けばいいのでしょうか? あちこち調べましたが、どうしてもわかりません。 ただし、if $a =~ /(abc|def|ghi)/ などで、=~ を !~ に直す、というのはナシです。あくまでも右辺の式の中で表現したいのですが…

  • 秀丸の検索・置換の正規表現の最短一致の挙動が変です

    秀丸の検索または置換の正規表現の 最短一致での挙動ですが、 /abc/def/ghi/jkl/mno/pqr/st/uvw.xyz の先頭にカーソルを置いた状態で、 (質問1) 正規表現のチェックボックスをチェックして /.*$ で検索すると /abc/def/ghi/jkl/mno/pqr/st/uvw.xyz が検索されると思うのですが 実際には /def/ghi/jkl/mno/pqr/st/uvw.xyz が検索されてしまいます。 なぜでしょうか。 (/abc/.*$とするとカーソルがある /abc/def/ghi/jkl/mno/pqr/st/uvw.xyz ではなく次の行以降の /abc/def/ghi/jkl/mno/pqr/st/uvw.xyz が検索されてしまいます?) (質問2) 正規表現のチェックボックスをチェックして /.*?$ で検索すると最短一致となるため /uvw.xyz が検索されると思うのですが 実際には /def/ghi/jkl/mno/pqr/st/uvw.xyz が検索されてしまいます。 なぜでしょうか。 (なお、/[^/]*$では/uvw.xyzが検索されます)

  • Perlのキャプチャ

    プログラム #!/usr/bin/perl my $str = "abc,def,ghi"; ($a,$b,$c) = $str =~ /(.*),(.*),(.*)/; print $a,"\n"; print $b,"\n"; print $c,"\n"; 実行結果 abc def ghi このようなプログラムで ($a,$b,$c) = $str =~ /(.*),(.*),(.*)/;は それぞれ$a,$b,$cにabc,def,ghiが入ります. キャプチャしたすべてを変数に入れるならこの方法ですが, defだけが欲しいのに変数を3つ用意する必要がないと思います. 間違った表記ですが, ($b) = $str =~ /(.*),(.*),(.*)/$2/; 2つ目にキャプチャした$2が変数$bに入るような表記は出来ないのでしょうか?

  • サクラエディタの正規表現での置換

    サクラエディタの正規表現での置換の方法について教えて下さい。 行の末尾が数字で終わらない行の改行コードを削除したいと考えています。 ---------- 元ファイル ---------- 000abc123 777def 456 333ghi789 222jk+ 111 ---------- ---------- 加工後 ---------- 000abc123 777def456 333ghi789 222jk+111 ---------- 「置換前」は『[^0-9]\n』を入力することで検索できましたが、 「置換後」に何を設定すれば良いのかわかりません。(または「検索対象」の設定を変える必要があるのかなど) 例えば置換後に何も設定しないと「777de456」とfが消えてしまうため、”f”を残した上で改行コードを削除したいのですが その方法がわかりません。 よろしくお願いいたします。

  • 正規表現が解読できません。

    ツールが対象ファイルを認識する規則が正規表現で記載されているのですが、 正規表現について無知なため、解読することができずに困っております。 ネット等で検索し、[A-Z0-9]や{4,4}など部分的には解読することができたのですが・・・ FILE_COPY.REGEX1=<ABC>\t.+\\\\ABC(\\\\.*)?\\\\[A-Z0-9]{4,4}[0-9]{3,3}[A-Z0-9]+\\\\[A-Z0-9]{4,4}[0-9]{3,3}[A-Z0-9]+\\.gz FILE_COPY.REGEX2=<DEF>\t.*\\\\[^\\\\]*(?<\!\\.tar) FILE_COPY.REGEX3=<GHI>\t.+\\.xml\\.gz どなたかお時間のある方がいらっしゃいましたら、ご教示いただけないでしょうか。 どうぞよろしくお願いいたします。

  • PHPで、フォルダーにあるファイルを配列に取り込みたい

    例えば次の様なフォルダーとファイルがあるとき \abc\a.txt \abc\b.doc \abc\def\b.doc \abc\ghi\a.txt \abc\ghi\b.doc 次の様な結果を得たいのですが、どうすれば良いでしょうか? $dir[/abc/a.txt] = "/abc/a.txt" $dir[/abc/b.doc] = "/abc/b.doc" $dir[/abc/def/b.doc] = "/abc/def/b.doc" $dir[/abc/ghi/a.txt] = "/abc/ghi/a.txt" $dir[/abc/ghi/b.doc] = "/abc/ghi/b.doc" 再帰関数でできそうに思うのですが、いくら考えても分かりません。 $path = "\abc"; function getfiles($path) {} print_r(getfiles($path)); みたいにして取り出せると助かります。 すみませんが教えてください。

    • ベストアンサー
    • PHP
  • データベースの関係の正規化の問題です

    データベース設計者が関係R(A,B,C,D,E, F,G) に対し,次の関数従属性を定義した.ここで,関係R は第1 正規形として与えられたものとする.関係R の第3 正規形はどれか? 関数従属性: A → D, C→E, C → G, EG → F (A) {A,B,C,D}, {E, F,G} (B) {A,B,C}, {D,E,G}, {F} (C) {A,B,C,D,E,G}, {D, F} (D) {A,B,C,D,E,G}, {E, F,G} (E) None of these ご回答よろしくお願いいたします。

  • 正規表現

    お世話になります。 カンマ区切りのデータの中からA=○○○のデータを取り出す正規表現を教えてください。 データの例 A=1000,B=300,C=500,D=200,...... A=200,B=200,C=300,D120 からA=○○○を抽出。 一応やってみたのが、”A=.*,”で検索してみましたが、 A=.....D=....すべて抽出してしまいます。 以上よろしくお願いします。

  • VBAで改行の入ったデータの正規表現について

    vbaで複数行のデータの一部を抜き出そうと思っています。 下記のようにすると、抜き出したデータの先頭に改行がついてしまいます。 何かいい方法はないでしょうか。 data = "start" & vbCrLf  & "ABC" & vbCrLf & "DEF" & vbCrLf & "GHI" & vbCrLf & "end" Set re = New RegExp re.Pattern = "start((.|\n)*?)end" re.MultiLine = True Set mc = re.Execute(data) For i = 0 To mc.Count - 1 MsgBox m.SubMatches(0) Next i 上記を実行すると vbCrLf  & "ABC" & vbCrLf & "DEF" & vbCrLf & "GHI" & vbCrLf となってしまいます。 ”ABC”から抜き出す場合、正規表現をどう書けばいいのでしょうか。 よろしくお願いします。

  • 【Oracle】NOT LIKE????

    例えば、 <テーブル1> A_C B C <テーブル2> ABC DEF GHI とあったとします。 このとき、テーブル1 LIKE テーブル2 として 該当しないデータを引きたいのですが… (この場合は、DEFとGHIです。) NOT LIKEを使うと、うまくいきません。 補足が必要であれば、補足をしますので よろしくお願いしますm(_ _)m

専門家に質問してみよう