正規表現の中の変数の表記のしかた

このQ&Aのポイント
  • 正規表現中の変数の表記方法やエスケープの必要性について質問です。
  • if文を使用した正規表現の記述が思った通りに動作しないため、解決策を求めています。
  • インターネット上の情報や持っている本では望んでいる情報にはたどり着けず、ヘルプを求めています。
回答を見る
  • ベストアンサー

正規表現の中の変数の表記のしかた

初歩的な質問なのですが、 if($test =~ /&n=$in{n}&/){} という正規表現は正しいのでしょうか? $in{n}が変数になるのですが、何か"などで囲まないといけないとかありますでしょうか? それとも別の箇所(例えば&や;)をエスケープしてやる必要があるのでしょうか? エラーは返ってきませんが、思った行動をおこしてくれず(必ずヒットするものがあるはずなのにif節内に行ってくれない)、また、何度もトライアンドエラーできる環境下のものではなく、さらにネットで正規表現について検索しても、持っている本に羅列されている内容ばかりで、今望んでいることについて触れているページが見つからないため、みなさまのお力お借りしたく思います。 どうぞよろしくお願いします。

  • choei
  • お礼率63% (286/451)
  • Perl
  • 回答数6
  • ありがとう数6

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

  • ベストアンサー
  • kumoz
  • ベストアンサー率64% (120/185)
回答No.5

$in{n} の {n} の n が実際はリテラルの数値である場合は、{n} が量指定子と解釈されてしまいます。 use strict; my %hash = qw(2 two two 2); print "match\n" if "xtwoy2z" =~ /$hash{two}/; # OK print "match\n" if "xtwoy2z" =~ /$hash{2}/; # エラー(Global symbol "$hash" ...) エラーメッセージから $hash は、スカラー変数と解釈されていることがわかります。use strict もなく、スカラー変数の $in がない場合は、/&n=$in{2}&/ は /&n={2}&/ という正規表現が適用されることになります。エラーを回避するためには、kmee さんの回答にある ${in{n}} とするか、キーをクォートして $in{'n'} のようにするか、あるいはキーを変数経由で渡すなどのいくつかの方法があります。

choei
質問者

お礼

回答ありがとうございました。 確かに数値のみの場合もありますので、量指定子として解釈されているのだろうと想像できます >${in{n}} とするか、$in{'n'} のようにするか、あるいはキーを変数経由で渡す そのような方法があったのですね 非常に参考になりました。 本当にありがとうございました

その他の回答 (5)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

おっと, そんな落とし穴があるんですか>#5. 知らなかった.... さておき, $test にどんな文字列が入っていて, $in{n} の値がどうなっているのかが分からなければ「正しい」かどうかなど判断のしようがありません.

choei
質問者

お礼

ありがとうございます >$test にどんな文字列が入っていて, $in{n} の値がどうなっているのか 確かに今回説明不足の部分が多かったです ($testはあまりにも長ったらしい文字列だったので省略してました)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

#2にもあるように、 $in{n}が 「ハッシュ%inの'n'要素」で合ってますか?、ということです。 「ハッシュ%inの$n要素」とか「リスト@inの$n要素」とかではないですよね? 期待通りにならない理由は、ここだけでは判断できません。 ・$in{n}に正規表現のメタ文字が含まれている。 →単純な比較ならindexがいいのでは? ・$test,$in{n}に期待した文字列が入っていない ・実はifが実行されているが、期待通りの動作になっていないので「if節が実行されていない」と誤解している ・そもそも、このif文を通っていない。(この外側にあるifやループで条件が不成立とか、このifのあるsubが呼ばれてないとか) 「何度もトライアンドエラーできる環境下のものではなく」とはありますけど、一つ一つ確認していくのが結局は近道だと思いますよ。「何度もトライアンドエラーできる環境」を作ってでも。

  • okmotokun
  • ベストアンサー率59% (92/155)
回答No.3

> 必ずヒットするものがあるはずなのにif節内に行ってくれない パターン/&n=$in{n}&/ は、 "&n=" . $in{n} . "&" ということですが、 検索文字列に含まれるのは、"&n=$in{n}&" ではありませんか。 if($test =~ /&n=$in{n}&/){...}elsif($test =~ /&n=$in{n}&/){...} でテストしてみたら、どうですか。

choei
質問者

お礼

ありがとうございます。 textファイルの中身を処理している構文なのですが、その構文では &n=×××& が入っているんです (×××は半角英数) つまり、&n=...ではなくtext上では&n=...です >テストしてみたら、どうですか 確かにトライアンドエラーが基本だと思うのですが、今回ちょっと簡単にテストして元に戻してといったことができない環境にあるので、できればスパッと回答頂きたいなと (長めのコードの中の一部分なので、そこだけにとラップかけて検証することができないので)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

m// は一種のクォートで, 区切りに ' を使う場合 (つまり m'') を除いて「ダブルクォートでくくった文字列」として解釈されます. 従って "&n=$in{n}&" と同様正しい, ということになります. $in{n} は「ハッシュ %in の, キー 'n' に対する値」ですね. 「思った行動をおこしてくれず」の根拠は不明.

choei
質問者

お礼

ありがとうございます >と同様正しい, ということになります 特に間違った構文ではないということなんですね >$in{n} は「ハッシュ %in の, キー 'n' に対する値」ですね はい、そうです >「思った行動をおこしてくれず」の根拠は不明 あ、分からなかったでしょうか、すみません。 ifの条件にマッチするものまでif節に入ってくれないという意味です ようはifの意味をなしてなかったというか

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

${in{n}} かなぁ。 ところで、 $in{n}であってます? $in{$n}とかではないですね?

choei
質問者

お礼

ありがとうございます。 >$in{n}であってます? 何があってるのかと聞かれているのかちょっとよく分からないので質問の回答になってるのか分かりませんが、記述ミスではありません。(正規表現内部でこの記述が正しいかどうかは分かりません。それをお尋ねしているので)

関連するQ&A

  • 正規表現の中の変数の中の演算子

    perlで正規表現を使おうとしています。 確認したい文字列は変数にしており その文字列には「?」が含まれています。 ------------------------ $str = "文字列" $exp = "test?aaa=bbb"; if ($str =~ /^sss.*${exp}$/){ #do something } ------------------------ これだと、ヒットしません。。 $expを"test\?aaa=bbb"にすることもできません。 正規表現にはこだわりません。 どうしたら、うまくマッチングできますかね。。 なにか案があれば教えてください。

    • ベストアンサー
    • Perl
  • 正規表現のパターンマッチがうまくいきません。

    正規表現のパターンマッチがうまくいきません。 入力した文字を含むデータを抽出しようとしているのですが、エラーは出ないものの、ヒットしません。 次の構文をそれぞれを試してみました。 目的は入力された文字$matchを含む$textを@queryに入れることです。 if($text =~ /$match/){ push(@query, $text); } if($text =~ /\$match/){ push(@query, $text); } if($text =~ /.*\$match.*/){ push(@query, $text); } if($text =~ m/.*\$match.*/){ push(@query, $text); } 半角英数で何度か試したのですが、どれでやってもヒットしてくれません。 どこをどのように訂正すればいいでしょうか。 お分かりの方ぜひご指導ください。 ちなみによく入力データを$in{aaa}とか$QUERY{aaa}などとまとめることがあるのですが、これを正規表現にそのまま入れるにはどうしたらいいでしょうか。 {}は量指定子になるのでこのままではエラーになるかなとも思うのですが、\などでエスケープすればいいのでしょうか。 上の$matchも元々は$in{aaa}なのですが、 $match = $in{aaa} として変えています。

    • ベストアンサー
    • Perl
  • javascriptの正規表現で変数を扱う

    javascriptの正規表現で変数を扱う方法がわからずに困っております。 下記スクリプトの●●●部分に変数をいれるとしたら、 どうすれば良いでしょうか? どなたかご教授ください。 宜しくお願いいたします。 if(/(?:^|\s)●●●(?:$|\s)/.test(obj.className)){

  • 正規表現

    変数$aのなかに変数$bが含まれていたらをperlの正規表現であらわすと どのようになるのでしょうか?if($a=~ /$b/)ではうまくいかないのですか?

    • ベストアンサー
    • Perl
  • Rubyの変数を含んだ正規表現について

    下のように正規表現でlineと 1=,2=などから始まる行を抽出する プログラムですが、どうやら正規表現の左辺(//の中身) には変数は使えないようです。iが文字として 認識されているようです。 解決策を教えてください。 while line = io.gets  20.times{ |i|   if /^i=(.*)/ =~ line   p $1  } end

  • 正規表現内での変数の扱いに関して

    正規表現内での変数の扱いに関して あるの変数の文字列が別の変数の文字列を冒頭に含むかどうか判別した上でその差分を抽出するコードを書こうとしています。 $a='komekoron'; $b='kome'; if($a=~/^$b(.+)$/){print $1}; このコードを実行すると「koron」が出力されます。 同様に以下のコードで「:」を出力させたいのですが上手くいきません。 $a='*:'; $b='*'; if($a=~/^$b(.+)$/){print $1}; 出力内容は「*:」 これは変数内の文字列がパタンとして扱われているのでしょうか。どうすれば意図する動作になるでしょうか。ご教授願います。

    • ベストアンサー
    • Perl
  • 正規表現について教えてください。

    Perlとは関係ないのですが、正規表現での置換ができるエディタで改行二つを一つにしたいです。 置換前 \n\n 置換後\n としてみたのですがうまくいきません。まちがってたら教えてください。 CRLFとか気にしないといけないのかな。

    • ベストアンサー
    • Perl
  • 正規表現をエスケープさせる関数はあるのでしょうか?\はつけたくないです。

    =head Perlの正規表現で例えば aa+aaという文字列をマッチさせたいのですがわざわざ\をいれずに、正規表現をエスケープするような関数? $k = ○○($k); はあるのでしょうか? =cut #my $k = 'aa+aa'; # だとマッチせず my $k = 'aa\+aa'; # だとマッチします。 my $dat = 'aa-aa+aa-aa'; if($dat =~ /($k)/){ print "見つかりました\n"; } print "OK\n"; exit; __END__

    • ベストアンサー
    • Perl
  • 正規表現

    正規表現のパターンを変数内に入れて評価することは 可能なんでしょうか? たとえば、 my $value = " 0123"; my $patern = "\s.+"; if( $value =~ /$patern/ ) ~略~ のような感じです。

    • ベストアンサー
    • Perl
  • perlにおける正規表現で、パターンに変数を使う場合について教えてください。

    変数と変数を正規表現にて比較する場合に、 if ($text =~ /$pattern/) { ... } とすると、「$pattern」を変数として認識しません。 「$」が位置指定子として認識されている?ようです。 「$pattern」を変数として認識させるにはどのようにすればよいのでしょうか? 「\$pattern」のように「\(バックスラッシュ)」を入れても認識されませんでした。

    • ベストアンサー
    • Perl