• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:正規表現の o オプションの意味が分かりません)

正規表現の o オプションの意味とは?

このQ&Aのポイント
  • 正規表現の o オプションは、変数展開を1回だけ行うという意味です。
  • o オプションを付けた正規表現では、正規表現を処理するためのメモリ領域に一度変数の値を取り込むため、変数の値が変わってもメモリ領域の値は変化しません。
  • 正規表現の変数を1つだけ使用する場合でも、o オプションを付けることで効率的に処理が行われます。しかし、変数が複数ある場合は考慮が必要です。

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

  • ベストアンサー
回答No.1

oオプションは「変数展開を最初の1回だけ行う」です。 一度でも $http{BODY}=~ /(?<=\[ No\.)([0-9]{$digit})(?= \/ $num)/o; を実行すると、実行した時点の値で、正規表現が固定されます。 例えば、$degitが「1」、$numが「2」の状態で、上記の行を1回でも実行すると、その行は、それ以降 $http{BODY}=~ /(?<=\[ No\.)([0-9]{1})(?= \/ 2)/o; として動作します。 2回目の実行前に、$digitや$numの値を変更しても、それは反映されません。これらがどんな値になってようが $http{BODY}=~ /(?<=\[ No\.)([0-9]{1})(?= \/ 2)/o; として動作します。 例えば $digit=1 $num=1 while( $num < 10) {   $http{BODY}=~ /(?<=\[ No\.)([0-9]{$digit})(?= \/ $num)/o;   .....   $num++; } とやっても   $http{BODY}=~ /(?<=\[ No\.)([0-9]{1})(?= \/ 1)/o; が9回行われるだけです。 怖いのは「ループカウンタとして$numは9まで増えて9回ループして終わるが、正規表現では、ずっと同じ値で処理される」って事です。 デバッグ表示で$numを表示したら、ちゃんと値は変化しているのに、値が変化しない正規表現が繰り返されるのです。 >ところが最初に読み込んだファイルではうまくマッチしたのですが、2番目のファイルではマッチしません。 当たり前です。 $numも$digitも「最初のファイルを読み込んだ時にセットされた値が展開されたあと、二度と評価されない」のですから、最初のファイルと同じ物しかマッチしません。 2番目のファイルを読み込んでも「最初のファイルで行った正規表現で実行する」ので、マッチする訳がありません。 >でも >$http{BODY}=~ /(?<=\[ No\.)([0-9]{$digit})/o; >だったらちゃんと$digitの値が変わったことに対応しているんです。 それは気のせいです。$digitが変化しても再評価されず、ずっと1回目の値で動いているけど、1回目も2回目以降も「偶然、マッチしてしまっただけ」です。

makoji
質問者

お礼

なるほど、件の正規表現から前方参照を削除した $http{BODY}=~ /(?<=\[ No\.)([0-9]{$digit})/o; の結果を見てみると、最初の$digitが1だと、他のファイルでも全て1桁の数字しかマッチしていませんでした。 うまく作動していると思われる o オプションは、全てs///の構文で用いたものでした。 もう一度調べなおすと、 s/Pattern/Replace/o の構文では、Replaceにある変数は書き換えられるようですが、Patternにある変数は書き換えられませんでした。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

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

Perl が言語として意図しているのは「それとも」の方です. つまり, //o は「『その正規表現』を最初に使うときのみ変数の値を展開する」ということを指示します. たとえば $m = 10; while ($m > 0) { $s = '1' x $m; if ($s -~ /1{$m}/o) { print "match\n"; } else { print "unmatch\n"; } --$m; } において o をつけたり消したりすると動作が変化します.

makoji
質問者

お礼

サンプルコードのおかげで理解しやすかったです。 ありがとうございました。

すると、全ての回答が全文表示されます。

関連するQ&A