2

Ruby スクリプトでstring#gsubは、正規表現として使用される文字列を生成するために使用しています。この正規表現は+文字と一致する必要があるため\+、エスケープするために使用しています。

このコード例は、私の混乱の原因を特定します。このコードで、作成したい正規表現は/a\+b/. ただし、 を使用する#gsubと、返される正規表現は/ab/.

string = 'a\+b'
expected = Regexp.new(string)
actual = Regexp.new('x'.gsub('x', string))

# expected returns /a\+b/
# actual returns /ab/

#gsub+文字に関する Ruby ドキュメントには何も見つかりませんでした。この結果を生み出すために何が起こっているのかを理解するのを手伝ってくれる人はいますか?

\x2B今のところ、コードを機能させるために、文字の ANSI 16 進コードである と照合してい+ます。それほど難読化されていないこれを達成する方法はありますか?

前もって感謝します!

4

4 に答える 4

3

Regexp.newここではあまり関係がないので無視しましょうgsub。それ自体だけです。

あなた\+は によって後方参照として解釈されていgsubます。ドキュメントから:

replacement が文字列の場合、一致したテキストに置き換えられます。形式のパターンのキャプチャ グループへの後方参照が含まれる場合があります\\d。ここで、dはグループ番号、またははグループ名です。二重引用符で囲まれた文字列の場合、両方の後方参照の前にバックスラッシュを追加する必要があります。ただし、置換内では、 などの特別な一致変数は現在の一致を参照しません。\\k<n>n$&

あまり明確ではありませんが (ドキュメントには「グループ番号」と記載されているため)、\+はグローバル変数$+*;に置き換えられます。ルビークイックリファレンスから:

$+: による$~。最後に成功した一致で一致した最上位のグループ。

何かをキャプチャすることでこれを証明できます。

'x'.gsub(/(x)/, 'a\+b')  #=> "axb"

これは、\+が正規表現からのキャプチャに置き換えられていることを示しています。パターンにはキャプチャがないため (文字列であるため)、後方参照は空の文字列に置き換えられ"ab"gsub.

"a\+b"実際にはそこにないため、使用は機能し\+ます:

"a\+b".bytes  #=> [97, 43, 98]
'a\+b'.bytes  #=> [97, 92, 43, 98]

* 意味的には同等ですが、match グローバル変数自体は、置換が完了するまで実際には設定されませんただしgsub、後方参照は、もちろん、置換が発生する前に設定されます。

于 2013-05-25T18:24:18.740 に答える
1

置換文字列内\+では、最後のキャプチャ グループの値を参照するために使用されます (たとえば、正規表現に 3 つのキャプチャ グループ\+が含まれている場合は と同じ\3です)。ブロック形式のgsub代わりに使用すると、これらの置換は実行されません。

string = 'a\+b'
actual = Regexp.new( 'x'.gsub('x') { string } )
# actual is now /a\+b/
于 2013-05-25T18:18:23.283 に答える
0

Regexpのunion方法は、文字列 (および/または Regexps) の組み合わせから正規表現を作成するためによく使用されます。これらの文字列をエスケープするため、ここでも役立ちます。

re = Regexp.union("a+b") # => /a\+b/ 
于 2013-05-25T18:18:59.977 に答える