What I need to do is convert something like this:
我需要做的是转换如下内容:
"id,name,user[id,email]"
into this array:
这个数组:
["id", "name", {"user"=>["id", "email"]}]
What is the best way to do that? I think some function like split
or scan
can help, but I don't have much knowledge in regex to solve this.
最好的方法是什么?我认为像split或scan这样的函数可以有所帮助,但是我在regex中没有太多的知识来解决这个问题。
2 个解决方案
#1
3
Just out of curiosity:
只是出于好奇:
▶ str = "id,name,user[id,email]"
▶ eval "[#{str.gsub(/(\w+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\w+/, ':\0')}]"
#⇒ [
# [0] :id,
# [1] :name,
# [2] {
# :user => [
# [0] :id,
# [1] :email
# ]
# }
#]
Disclamer: to use eval
in production one must understand risks.
Disclamer:在生产中使用eval必须了解风险。
UPD Safe eval
ing (note that every ASCII \w
symbol is converted to it’s wide pair from UTF-8 to prevent injection; not the best way around, but it works nicely unless you have ruby functions named with wide characters):
UPD安全报警(注意,每个ASCII \w符号从UTF-8转换为宽对,以防止注入;这并不是最好的方法,但是它可以很好地工作,除非你有用宽字符命名的ruby函数):
▶ safe = str.gsub(/\w/) do |e|
▷ e.each_codepoint.map do |cp|
▷ cp + 0xFF00 - 0x0020
▷ end.pack('U')
▷ end
#⇒ "id,name,user[id,email]"
▶ eval "[#{safe.gsub(/(\p{L}+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\p{L}+/, ':\0')}]"
#⇒ [
# [0] :id,
# [1] :name,
# [2] {
# :user => [
# [0] :id,
# [1] :email
# ]
# }
#]
Now you are free to turn keys back from wide characters to ASCII.
现在您可以*地将键从宽字符转回ASCII。
#2
0
string = "id,name,user[id,email]"
parts = string.split(/[\,,\[,\]]/)
[parts[0], parts[1], {parts[2] => [parts[3], parts[4]]}]
You may also want to have some validation or not use all the parts if the first id is supposed to be the same as the second.
如果第一个id应该与第二个id相同,您可能还想进行一些验证,或者不使用所有的部分。
#1
3
Just out of curiosity:
只是出于好奇:
▶ str = "id,name,user[id,email]"
▶ eval "[#{str.gsub(/(\w+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\w+/, ':\0')}]"
#⇒ [
# [0] :id,
# [1] :name,
# [2] {
# :user => [
# [0] :id,
# [1] :email
# ]
# }
#]
Disclamer: to use eval
in production one must understand risks.
Disclamer:在生产中使用eval必须了解风险。
UPD Safe eval
ing (note that every ASCII \w
symbol is converted to it’s wide pair from UTF-8 to prevent injection; not the best way around, but it works nicely unless you have ruby functions named with wide characters):
UPD安全报警(注意,每个ASCII \w符号从UTF-8转换为宽对,以防止注入;这并不是最好的方法,但是它可以很好地工作,除非你有用宽字符命名的ruby函数):
▶ safe = str.gsub(/\w/) do |e|
▷ e.each_codepoint.map do |cp|
▷ cp + 0xFF00 - 0x0020
▷ end.pack('U')
▷ end
#⇒ "id,name,user[id,email]"
▶ eval "[#{safe.gsub(/(\p{L}+)\[(.*?)\]/, '{\1=>[\2]}').gsub(/\p{L}+/, ':\0')}]"
#⇒ [
# [0] :id,
# [1] :name,
# [2] {
# :user => [
# [0] :id,
# [1] :email
# ]
# }
#]
Now you are free to turn keys back from wide characters to ASCII.
现在您可以*地将键从宽字符转回ASCII。
#2
0
string = "id,name,user[id,email]"
parts = string.split(/[\,,\[,\]]/)
[parts[0], parts[1], {parts[2] => [parts[3], parts[4]]}]
You may also want to have some validation or not use all the parts if the first id is supposed to be the same as the second.
如果第一个id应该与第二个id相同,您可能还想进行一些验证,或者不使用所有的部分。