10

正規表現グループ マッチングの質問を読んでいましたが、正規表現からキャプチャ グループを参照する方法が 2 つあります。

  1. マッチ文字列メソッドなどstring.match(/(^.*)(:)(.*)/i).captures
  2. から取得した $1、$2 などの Perl 風のキャプチャ グループ変数if match =~ /(^.*)(:)(.*)/i
  3. 更新: 0xCAFEBABE で述べたように、3 番目のオプションもあります - last_matchメソッド

どちらが良いですか?1) では、安全のために if ステートメントを使用して nil を防ぐ必要があるため、情報を抽出するだけではどうですか? 文字列キャプチャ メソッドを呼び出す 2 番目のステップの代わりに。したがって、オプション 2) の方が便利に思えます。

4

2 に答える 2

4

単純なタスクの場合、疑似変数$1などに直接アクセスする方が短くて簡単かもしれませんが、複雑になると、MatchDataインスタンスを介してアクセスすることが (ほぼ) 唯一の方法になります。

たとえば、入れ子になっているとしますgsub:

string1.gsub(regex1) do |string2|
  string2.gsub(regex2) do
    ... # Impossible/difficult to refer to match data of outer loop
  end
end

内側のループ内で、外側のキャプチャされたグループを参照したいとしますgsub。、 などを呼び出す$1$2、正しい結果が得られません。これは、内部gsubループを実行することによって最後の一致データが変更されたためです。これがバグの元になります。

マッチ データを介してキャプチャされたグループを参照する必要があります。

string1.gsub(regex1) do |string2|
  m1 = $~
  string2.gsub(regex2) do
    m2 = $~
    ... # match data of the outer loop can be accessed via `m1`.
        # match data of the inner loop can be accessed via `m2`.
  end
end

簡単に言うと、簡単なタスクで短いハック的なことをしたい場合は、疑似変数を使用できます。コードをより構造化して拡張可能にしたい場合は、一致データを介してデータにアクセスする必要があります。

于 2013-07-19T10:57:17.170 に答える