parsing in ruby

2019-08-22 07:03发布

I have this Hash:

cookie = {"fbs_138415639544444"=>["\"access_token=138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt&expires=0
&secret=64aa8b3327eafbfd22ba070b&session_key=5c682220fa7dsfdsafas3523340
&sig=4a494b851ff43d3a58dfa8757b702dfe&uid=503523340\""], 
"_play_session"=>["fdasdfasdf"]}

I need to get the substring from right after access_token= to right before &expires. The problem is that the number in the key fbs_138415639544444 changes every time, just the part fbs_ remains constant.

Any idea how to only get:

"138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt"

6条回答
混吃等死
2楼-- · 2019-08-22 07:21

This is a common task when decoding parameters and queries in HTML URLs. Here's a little method to break down the parameters into a hash. From there it's easy to get the value you want:

def get_params_hash(params)
  Hash[ *params.split('&').map{ |q| q.split('=') }.flatten ]
end

p get_params_hash(cookie['fbs_138415639544444'].first)['"access_token']

# >> "138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt"

In Ruby 1.9+, hashes retain their insertion order, so if the hash always has the value you want as its first entry, you can use

cookie.keys.first #=> "fbs_138415639544444"

otherwise use:

cookie.keys.select{ |k| k[/^fbs_/] }.first #=> "fbs_138415639544444"
查看更多
你好瞎i
3楼-- · 2019-08-22 07:24

Since the key changes, the first step is to get right key:

key = cookie.keys.select {|k| k =~ /^fbs_/}.first

This matches them if they begin with the text "fbs_". The first match is returned.

Next you can get the other value by a few (ugly) splits:

cookie[key].first.split('=')[1].split('&').first

Using a regex might be a bit cleaner, but it depends on what the valid characters are in that string.

查看更多
Luminary・发光体
4楼-- · 2019-08-22 07:32

I never code in ruby, but this sounds like a typical task for split function. you just need to split this

"\"access_token=138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt&expires=0 &secret=64aa8b3327eafbfd22ba070b&session_key=5c682220fa7dsfdsafas3523340 &sig=4a494b851ff43d3a58dfa8757b702dfe&uid=503523340\""

by & symbol. The first element of result array will be:

"\"access_token=138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt"

and after split it by =, and the second element of result array should be:

138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt

查看更多
【Aperson】
5楼-- · 2019-08-22 07:32

Regexs are brittle so I wouldn't use those when the reality is you are parsing query string params in the end so use the CGI lib:

> require 'cgi'
=> true 
> cookie = {"fbs_138415639544444"=>["\"access_token=138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt&expires=0&secret=64aa8b3327eafbfd22ba070b&session_key=5c682220fa7dsfdsafas3523340&sig=4a494b851ff43d3a58dfa8757b702dfe&uid=503523340\""], "_play_session"=>["fdasdfasdf"]}
> CGI.parse(cookie.select {|k,v| k =~ /^fbs_/}.first[1][0])["\"access_token"][0]
=> "138415639544444|5c682220fa7ebccafd97ec58-503523340|9HHx3z7GzOBPdk444wtt"
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-08-22 07:34

This is how i solved the problem...

  access_token_key = cookies.keys.find{|item| item.starts_with?('fbs_') }
  token = cookies[access_token_key].first
  access_token = token.split("&").find{|item| item.include?('access_token') }
  fb_access_token = access_token.split("=").find{|item| !item.include?('access_token') }
查看更多
三岁会撩人
7楼-- · 2019-08-22 07:39

If you only need the access_key part, then a regex is probably easiest.

cookie["fbs_138415639544444"][0] =~ /access_token\=([-\w\d\|]*)&/
access_key = $1

Here the access_key is in the first capture group and you can get it with $1.

A better option if you'll need other parts of the string (say the session_key), would probably be to use a couple splits and parse the string into it's own hash.

Edit: Just realized you need the key too.

key = cookie.each_key.find { |k| k.start_with? "fbs_" }

Then you can use key to get the value.

查看更多
登录 后发表回答