2012-04-20 13 views
2

私はコンテンツと単純なテキストファイルがあります。ルビーダブルスラッシュGSUB問題

patent-inv 

を私はそれをやったパート1 \\その2

特許-INVを交換するつもりですこのような方法:

source_file = IO.read("#{Rails.root}/my_userdata/1.txt") 
source_file.gsub!('<<<patent-inv>>>', "part1\\\\part2")    
File.open("#{Rails.root}/my_userdata/2.txt", "wb") {|f| f.write source_file } 

しかし、ファイルに私が得た: パート1の\のパート2を

私はいくつかの方法を試してみましたが、私は同じ結果を得た:

source_file.gsub!('<<<patent-inv>>>', "part1\\\\part2") => "part1\part2" 
source_file.gsub!('<<<patent-inv>>>', "part1\\\part2") => "part1\part2" 
source_file.gsub!('<<<patent-inv>>>', "part1\\part2") => "part1\part2" 

誰もがこの奇妙な行動を見つける私を助けてもらえますか?

+1

を試してみてください。さらに、バックスラッシュは のgsub/sub置換文字列で特別な意味を持ちます。したがって、もう一度二重にする必要があります。つまり、 の代わりに1つのバックスラッシュごとに4つのバックスラッシュが必要な理由は です。それは奇妙ですが、それは長い間仕様です。私は考えていない 我々はこの動作を変更することができます。代わりにブロックを使用できます。 ** printf "b" .gsub(/ b /){'\\'} ** –

答えて

3

以下は私のために働くものです。ターミナルで試しましたか?結果を出力するとエスケープされません。

> a = "<<<patent-inv>>>" 
> a.gsub("<<<patent-inv>>>", "part1\\\\part2")  
=> "part1\\part2" 

出力はここであなたがそれを望むように表示出力されている EDIT

> puts a part1\part2 > p a "part1\\part2" > puts a.inspect "part1\\part2" 

puts間とpどのように変化するかをあなたが見ることができます。

1.9.2-p290 :037 > a.gsub!("<<<patent-inv>>>", "part1\\\\\\part2") 
=> "part1\\\\part2" 
> p a 
"part1\\\\part2" 
=> "part1\\\\part2" 
> puts a 
part1\\part2 
=> nil 

エスケープされていないときは、バックスラッシュ4個がバックスラッシュ2個に等しいことがわかります。したがって、バックスラッシュを正しく表示するためには、バックスラッシュを4回生成してから生成する必要があります。

+0

はい、コンソールで動作します。しかし、それはなぜ機能するのですか? ** source_file.gsub( 'patent-inv'、「part1 \\ part2」)=>「part1 \\ part2」**しかし、なぜ?? –

+0

出力すると、 "\\"は "\"にエスケープされません。私の編集を参照してください。 – Gazler

+0

これはコンソールではわかります。しかし、私の質問はファイルに書き込むことでした。なぜ予期しない動作がありますか? –

2

EDIT全体としての回答を修正します。私はputsが出力されたときに\シンボルをエスケープし、実際にそこにいなくても目標を達成したと私は思っていました。しかし、今私はそれが働いている。私の実験を参照してください。

> str = "patent-inv" 
=> "patent-inv" 
> str.gsub!('patent-inv', "part1\\\\part2") 
=> "part1\\part2" 
> str.chars.each { |t| puts t } 
p 
a 
r 
t 
1 
\ 
p 
a 
r 
t 
2 
=> "part1\\part2" 
> str = "patent-inv" 
=> "patent-inv" 
> str.gsub!('patent-inv', "part1\\\\\\part2") 
=> "part1\\\\part2" 
> str.chars.each { |t| puts t } 
p 
a 
r 
t 
1 
\ 
\ 
p 
a 
r 
t 
2 
=> "part1\\\\part2" 

基本的に私は実際には文字列に含まれているものを文字参照するstr.chars.each { |t| puts t }を使用しています。ご覧のとおり、使用する正しいパターンはpart1\\\\\\part2です。あなたは ダブルスラッシュに必要なので、**バックスラッシュは、文字列内の特殊なエスケープの意味を持つ:マッツが言ったように

+0

コンソールでは動作し、同時に動作しません:** source_file.gsub( 'patent-inv'、 "part1 \\ part2")**同じ結果を返します** "part1 \\ part2 "**。しかし、なぜ?? –

+0

私は完全に間違っていたので私の答えを訂正しました。私は出力を誤解して解釈していました。実際には、文字列にはただ1つの '\'しか含まれていませんが、エスケープされた文字は2倍に見えます。 –

1

は**

source_file.gsub!('<<<patent-inv>>>', "part1\\\\\\\\part2") => "part1\part2" 

=)

+0

おそらくsource_file.gsub!( '<< >>'、 "part1 \\\\\\\\\\ part2")=> "part1 \ part2" ??? )) –

+0

実際には、自分のコードをテストしました。ファイルから読み込んで別のものに書き込みます。あなたはGSUBとき\\\\\\\\あなたが書くとき\\\\、\\\\に変換助言のための – gayavat

+0

OK、感謝を\\に変換します –