4

私の質問は、cmd ARGVのSTDINを変換する方法、または16進数からASCIIに変換する方法です。

16進文字列を変数に割り当てた場合、印刷すると変換されることを知っています。

hex_var = "\x41\41\x41\41"
puts hex_var

結果は次のようになります

AAAA

しかし、(ARGVまたはgets)によってコマンドラインから値を取得する必要があります

私はこの行を持っていると言う

s = ARGV

puts s
# another idea
puts s[0].gsub('x' , '\x')

それから私は走った

ruby  gett.rb \x41\x41\x41\x41 

私は得た

\ x41 \ x41 \ x41 \ x41

それを機能させる方法はありますか?

4

2 に答える 2

1

ここで扱っている問題がいくつかあります。あなたがすでに対処しようとした最初のものですが、あなたの解決策は本当に理想的ではないと思います。コマンドライン引数で渡すバックスラッシュはシェルによって評価されており、rubyスクリプトに到達することはありません。スクリプトでgsubを実行するだけの場合、それらを渡す理由はありません。それを自分のやり方で実行すると、引数の「x」は、使用されていないものも含めてスワップアウトされます。 16進数を示します。可能であれば、引数の\を二重にエスケープすることをお勧めします。値がどこから来ているのかという文脈がなければ、実際に良い方法で言うのは難しいです。

ruby gett.rb \\x41\\x41

そうすれば、ARGVは実際には'\ x41 \ x41'を取得します。これは、必要なものに近くなります。

ただし、ARGV引数は式の置換なしで作成されるため(一重引用符で囲まれているように)、それでも正確には望みどおりではありません。したがって、Rubyは、望まない場合でも、その\をエスケープしています。基本的に、それを二重引用符で囲んでいるかのように再評価する必要があります。

eval('"%s"' % s)

ここで、sは文字列です。

したがって、すべてをまとめると、次のいずれかになります。

# ruby gett.rb \x41\x41

ARGV.each do |s|
  s = s.gsub('x' , '\x')
  p eval('"%s"' % s)
end
# => "AA"

# ruby gett.rb \\x41\\x41

ARGV.each do |s|
  p eval('"%s"' % s)
end
# => "AA"
于 2012-05-05T17:20:03.653 に答える
1

コンソールに入力されたバックラッシュはシェルによって解釈され、2つのバックラッシュを続けて入力しない限り、Rubyスクリプトには反映されません。この場合、スクリプトは文字通りのバックラッシュを取得し、それに続く16進文字コードの自動変換は行われません。バックラッシュ。

スクリプトの最後の行を次のように置き換えると、これらのエスケープされたコードを手動で文字に変換できます。

puts s.gsub(/\\x([[:xdigit:]]{1,2})/) { $1.hex.chr }

次に、ダブルバックラッシュ入力で実行します。

$ ruby gett.rb \\x41\\x42\\x43
ABC

getなどを介してユーザー入力をフェッチする場合、文字エスケープごとにユーザーが入力する必要があるバックスラッシュは1つだけです。これは、実際に文字通りのバックスラッシュとしてスクリプトに渡され、上記のgsub呼び出しによって正しく処理されるためです。


コマンドライン引数を解析する別の方法は、シェルに文字エスケープを解釈させることです。これを行う方法は、使用しているシェルによって異なります。bashを使用する場合は、次のように実行できます。

$ echo $'\x41\x42\x43'
ABC
$ ruby -e 'puts ARGV' $'\x41\x42\x43'
ABC
于 2012-05-05T21:15:05.723 に答える