问题描述
我得到了以下字符串,我需要获取 Pizzahut: 和 | 之间的所有值。
ABC:2fg45rdvsg|Pizzahut:j34532jdhgj|Dominos:3424232|Pizzahut:3242237|Wendys:3462783|Pizzahut:67688873rg|
我有 RegExpression .scan(/(?<=Pizzahut:)([.*\s\S]+)(?=\|)/)
但它可以获取
"j34532jdhgj|Dominos:3424232|Pizzahut:3242237|Wendys:3462783|Pizzahut:67688873rg|"
结果应该是: 34532jdhgj,3242237,67688873rg
解决方法
你可以使用
s='ABC:2fg45rdvsg|Pizzahut:j34532jdhgj|Dominos:3424232|Pizzahut:3242237|Wendys:3462783|Pizzahut:67688873rg|'
p s.scan(/Pizzahut:([^|]+)/).flatten
# => ["j34532jdhgj","3242237","67688873rg"]
参见 this Ruby demo 和 Rubular demo。
您似乎不可能将 Pizzahut
作为另一个词的一部分,但有可能使用带有词边界 /\bPizzahut:([^|]+)/
的版本。
Pizzahut:([^|]+)
匹配 Pizzahut:
,然后将管道以外的任何一个或多个字符捕获到组 1(使用 ([^|]+)
)。
请注意,String#scan
仅在模式包含捕获组时才返回捕获,因此您不需要使用环视。
我不知道你为什么要在这里使用 regex 解决方案;该输入字符串在我看来显然是结构化的,您可能会通过在分隔符上拆分它以将其转换为更方便的数据结构来做得更好。
像这样:
input = "ABC:2fg45rdvsg|Pizzahut:j34532jdhgj|Dominos:3424232|Pizzahut:3242237|Wendys:3462783|Pizzahut:67688873rg"
converted_input = input
.split('|') #=> ["ABC:2fg45rdvsg","Pizzahut:j34532jdhgj",... ]
.map { |pair| pair.split(':') } #=> [["ABC","2fg45rdvsg"],["Pizzahut","j34532jdhgj"],... ]
.group_by(&:first) #=> {"ABC"=>[["ABC","2fg45rdvsg"]],"Pizzahut"=>[["Pizzahut",... ],"Dominos"=>[["Dominos","3424232"]],... ]
.transform_values { |v| v.flat_map(&:last) }
(上述一系列转换只是一种可能的方式;您可能会想出十几个类似的替代步骤来将此输入转换为如下所示的相同哈希!例如,通过使用 reduce
甚至CSV
库。)
最终结果如下:
converted_input = {
"ABC" => ["2fg45rdvsg"],"Pizzahut" => ["j34532jdhgj","67688873rg"],"Dominos" => ["3424232"],"Wendys" => ["3462783"]
}
既然数据格式方便了,像你原来的请求那样获取数据就变得微不足道了:
converted_input["Pizzahut"].join(',') #=> "j34532jdhgj,3242237,67688873rg"
(虽然很可能将其保留为 Array
,而不是逗号分隔的 String
!!)