2

たまたま変数に格納されている文字列オブジェクトから正規表現を構築しようとしています。

私が直面している問題は、「\ d」などのエスケープされたシーケンス (文字列内) が結果の正規表現にならないことです。

Regexp.new("\d") => /d/

一重引用符を使用すると、厳しいですが、問題なく動作します。

Regexp.new('\d') => /\d/

しかし、私の文字列は変数に格納されているため、常に二重引用符で囲まれた文字列を取得します。

正規表現コンストラクターで使用できるように、二重引用符で囲まれた文字列を単一引用符で囲まれた文字列に変換する方法はありますか?

(二重引用符の文字列補間機能を使用したい)

元。:

email_pattern = "/[a-z]*\.com"
whole_pattern = "to: #{email_pattern}"
Regexp.new(whole_pattern)

読みやすくするために、エスケープ文字のエスケープを避けたいと思います。

"\\d"
4

2 に答える 2

4

問題は、一重引用符を使用するか二重引用符を使用するかによって、文字列が完全に異なることです。

"\d".chars.to_a
#=> ["d"]

'\d'.chars.to_a
#=> ["\\", "d"]

したがって、二重引用符を使用している場合、一重引用符\はすぐに失われ、定義上、次のように復元することはできません。

"\d" == "d"
#=> true

したがって、エスケープが行われる前に、文字列に何が含まれていたかを知ることはできません。@FrankSchmittが提案したように、二重の円記号を使用するか、一重引用符で囲みます。他に方法はありません。

ただし、オプションがあります。文字列ではなく、正規表現自体として正規表現パーツを定義できます。それらは期待どおりに動作します。

regex1 = /\d/
#=> /\d/

regex2 = /foobar/
#=> /foobar/

#{}次に、文字列から正規表現ソースを作成する代わりに、スタイル補間を使用して最終的な正規表現を作成できます。

regex3 = /#{regex1} #{regex2}/
#=> /(?-mix:\d) (?-mix:foobar)/

あなたの例を反映すると、これは次のように解釈されます。

email_regex = /[a-z]*\.com/
whole_regex = /to: #{email_regex}/
#=> /to: (?-mix:[a-z]*\.com)/

また、面白いと思うかもしれませんRegexp#escape。(ドキュメントを参照してください

%r{<your regex here>}(スラッシュを使用して)さらにエスケープの問題が発生した場合は、文字をエスケープする必要がない、の代替正規表現リテラル構文を使用することもできます/。例えば:

%r{/}
#=> /\//

ただし、バックスラッシュ\を回避することはできませ\\ん。

于 2012-11-06T15:07:43.203 に答える
0

文字列を一重引用符で作成します。

 s = '\d'
 r = Regexp.new(s)

またはバックスラッシュを引用します。

 s = "\\d"
 r = Regexp.new(s)

どちらも機能するはずです。

于 2012-11-06T14:11:32.623 に答える