Ruby: 正規表現の後方参照を「正しく」エスケープする方法(翻訳)

概要 原著者の許諾を得て翻訳・公開いたします。 英語記事: Idiosyncratic Ruby: Escape Back Referencing 原文公開日: 2017/12/25 著者: Jan Lelis サイト: Idiosyncratic Ruby Ruby: 正規表現の後方参照を「正しく」エスケープする方法(翻訳) Rubyには、直近の正規表現マッチの追加情報(グループキャプチャなど)にアクセスする方法がいくつもあります。ドル記号$付きの$`や$&や$’や$1〜$9や$+などの特殊変数を用いる方法もあれば、MatchDataオブジェクト$~を使う方法もあります。これらは、正規表現にマッチしたメソッドを使った後に利用可能になります。また、メソッドがブロックをサポートしていれば、そのブロック内で既に利用できます。 しかし、文字列置き換えメソッドであるString#gsubやString#subでもサポートされている特殊な文字列処理が存在します。ここで置き換えに用いられる文字列(2番目のパラメータ)には後方参照(back reference)を含められ、これは対応する特殊変数に似た振る舞いを示します。 “Idiosyncratic Ruby”.sub(/(\w+) (\w+)/, ‘\2 \1’) # => “Ruby Idiosyncratic” 訳注: 後方参照についてはMSDNの『後方参照』もどうぞ。 1. 正規表現の特殊変数と後方参照の対応関係 Perl的な記法 後方参照 動作 例 $& ‘\&’, ‘\0’1 マッチ “abc”.gsub(/.*/, ‘\&\&’) # => “abcabc” $` ‘\`’ マッチ直前の文字 “abc”.gsub(/b/, ‘\`’) # => “aac” $’ ‘\\\” マッチ直後の文字 “abc”.gsub(/b/, ‘\\\”) # => “acc” $12 ‘\1’ 1番目のキャプチャ “abc”.gsub(/(a)b(c)/, ‘\1’) # => “a” $+ ‘\+’ 最後のキャプチャ “abc”.gsub(/(a)b(c)/, ‘\+’) # => “c” $~[:name] ‘\k<name>’ 名前付きキャプチャ “abc”.gsub(/(?<name>a)bc/, ‘\k<name>’) # => “a” 2. エスケープについて Rubyで後方参照そのものをエスケープしようとすると絶対的に混乱を招きます。文字列を一重引用符’で囲む場合は、バックスラッシュ\を1つまたは2つ使わなければなりません。文字列を二重引用符”で囲む場合はバックスラッシュを2つ(場合によっては3つ)使わなければなりません。\’のエスケープには特に注意が必要です3。 訳注: 原文のbackspaceはbackslashの誤りと判断しました。 X ‘\X’ ‘\\X’ ‘\\\X’ “\X” “\\X” “\\\X” “\\\\X” & マッチ マッチ “\\&” “&” マッチ マッチ “\\&” ` マッチ直前の文字 マッチ直前の文字 “\\`” “`” マッチ直前の文字 マッチ直前の文字 “\\`” ‘ “‘” – マッチ直後の文字 “‘” マッチ直後の文字 マッチ直後の文字 “\\'” 01 マッチ マッチ “\\0” “\u0000” マッチ “\\\u0000” “\\0” 12 1番目のキャプチャ 1番目のキャプチャ “\\1” “\u0001” 1番目のキャプチャ “\\\u0001” “\\1” + 最後のキャプチャ 最後のキャプチャ “\\+” “+” 最後のキャプチャ 最後のキャプチャ “\\+” k<name> 名前付きキャプチャ 名前付きキャプチャ “\\k<name>” “k<name>” 名前付きキャプチャ 名前付きキャプチャ “\\k<name>” 訳注: 上のエスケープをRuby 2.5.1で確認しました。 関連記事 [Ruby] Kernelの特殊変数をできるだけ$記号なしで書いてみる $0は正規表現のマッチとは無関係であるにもかかわらず、\0は有効な後方参照です。 ↩ ↩ 「N番目のキャプチャ」も同様 ↩ ↩ ‘を\’(バックスラッシュとクォート、後方参照なし)に置き換えたい場合は、’\\\\\”を置き換え文字列とします。 ↩