QA@IT

splitでバックスラッシュの入った文字を区切り文字としたい

5787 PV

現在Rubyで、バックスラッシュの入った文字が入った文字列がAPIで返って来ている為、それを区切り文字としてsplitで分けたいのですが、どうしてもうまくいきません。

以下のように、バックスラッシュ記法によるバックスラッシュ2つでやっても2つのまま処理されてしまい、悩み中です。

"User\AAA\VVV\BBB".split("\\")

どのようにすればよろしいでしょうか?

追記:
皆さんありがとうございます。
ダブルクォートの場合、バックスラッシュ記法になってしまう為、\である必要がありますが、API取得なので変更は出来ません。その為、シングルクォートで行う必要があることが分かりました。

しかし、一度変数へ入った場合、シングルクォートで処理する事が出来ませんでした。。
説明足らずで申し訳ありません。

AWS_APIで取得した結果がこれなんです・・。

回答

この質問の本題とはずれますが、AWSなら自前でレスポンスをパースするよりも素直に aws/aws-sdk-ruby を使った方が事故は少ない気がしますね ヾ(〃><)ノ゙☆

編集 履歴 (0)
  • おお、ありがとうございます!!
    自前で頑張ってましたが、こちらを使ってみたいと思います。
    -

AWS_APIで取得した結果がこれなんです・・。

これの意味が、
「APIで取得してみた文字を出力してみたらバックスラッシュは一つだった」
という意味であればそこに認識違いがあります(違ったら読み飛ばしてください)。

以下のように、変数に格納後出力して見える文字列にはバックスラッシュは一つです。

irb(main):001:0> v = "User\\AAA\\VVV\\BBB"
=> "User\\AAA\\VVV\\BBB"

irb(main):002:0> puts v
User\AAA\VVV\BBB
=> nil

しかしこれがrubyの中でどういう文字と一致するのかと言えば

irb(main):003:0> v == "User\\AAA\\VVV\\BBB"
=> true
irb(main):004:0> v == "User\AAA\VVV\BBB"
=> false

という結果になります。
APIで取得した文字がどういう文字と一致するか確認されるとよいでしょう。

それと、

しかし、一度変数へ入った場合、シングルクォートで処理する事が出来ませんでした。。

これをどのように実行してダメだったか示された方が回答しやすいと思います。

編集 履歴 (0)
  • ありがとうございます。解決出来ました。
    >>「APIで取得してみた文字を出力してみたらバックスラッシュは一つだった」この言葉で気付かされました。 実際の文字列をputsによる確認をした所、¥tが文字として含まれており、タブ文字として評価されてました。
    サンプルがよくありませんね。
    -

言葉足らずだった為、追記しました。

編集 履歴 (0)

ようするに

p "User\AAA\VVV\BBB".split("\\") # 「\」がバックスラッシュ記法だと間違えられる
p 'User\AAA\VVV\BBB'.split("\\") # 期待通り動作する

ということですよね?そもそもダブルクォートだとバックスラッシュ記法が有効になりますから、例文にあるような

"User\AAA\VVV\BBB".split("\\")

は「\A」がベルをなぜか大文字で書いたもので「\B」はバックスペースをなぜか大文字で(略)、「\V」が謎の文字となっています。個人的にはこれが一番興味があります。それはさておき、意図した文字列はおそらく下のものだったはずです。

"User\\AAA\\VVV\\BBB".split("\\")

バックスラッシュ記法が有効なダブルクォートで記述するのであればこちらが正しい書き方になります。APIから文字をどのように受け取っているのかわかりませんから根本的な対処方法は提示できないのですが、これがヒントになると思います。

でも、個人的な意見では、splitの引数もダブルクォートだと気持ち悪いので正規表現にしたいです。

"User\\AAA\\VVV\\BBB".split /\\/

でも、あんまり神経質だと友達が減るので、そこは適当でいいと思います。

ちなみに5年くらい前にLL言語のsplit関数の挙動の相違というのがちょっと話題になったことがあります。
http://0xcc.net/blog/archives/000201.html
http://d.hatena.ne.jp/boscono/20080902
http://selfkleptomaniac.org/archives/674
この辺の、まあどーでもいいっちゃどーでもいいことが気になるようになれば、(´・ω・`)やぁ。ようこそバーボンハウスへ。

編集 履歴 (1)
  • ありがとうございます。
    >splitの引数もダブルクォートだと気持ち悪いので正規表現にしたい
    これにすると、シングルクォートでもダブルクォートでも同じ結果になりますね。こちらの方が挙動が同じなので私も好みです。
    -

バックスラッシュは「二つで一つ」です。これはレシーバー側の文字列でも同じです。
"User\\AAA\\VVV\\BBB".split("\\")とやってみましょう。

puts "User\AAA\VVV\BBB"とやれば、\A\Vが無効なエスケープとして無視されている様が分かると思います。

編集 履歴 (0)
  • ありがとうございます。
    やはりバックスラッシュは2文字として処理される為、\\である必要がありますね。
    -
"User\\AAA\\VVV\\BBB".split('\\') #=> ["User", "AAA", "VVV", "BBB"]
'User\AAA\VVV\BBB'.split('\\') #=> ["User", "AAA", "VVV", "BBB"]

ということでしょうか??

編集 履歴 (0)
  • ありがとうございます。
    バックスラッシュ記法について理解が深まり、
    解決に近づくことが出来ました。
    しかし、あと一歩届かずでした。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。