大约有一百种方法可以解决这个问题。一个非常简单的方法是:
str = "something: this, this and that, that, other stuff, another: name, another name, last: here"
key = nil
str.scan(/\s*([^,:]+)(:)?\s*/).each_with_object({}) do |(val, colon), hsh|
if colon
key = val.to_sym
hsh[key] = []
else
hsh[key] << val
end
end
# => {
# something: ["this", "this and that", "that", "other stuff"],
# another: ["name", "another name"],
# last: ["here"]
# }
它通过使用以下正则表达式扫描字符串来工作:
/
\s* # any amount of optional whitespace
([^,:]+) # one or more characters that aren't , or : (capture 1)
(:)? # an optional trailing : (capture 2)
\s* # any amount of optional whitespace
/x
然后它遍历匹配项并将它们放入哈希中。当匹配有一个尾随冒号(捕获 2)时,将创建一个新的哈希键,其中包含一个空数组作为值。否则,值(捕获 1)将添加到最新键的数组中。
或者……
一种不太直接但更聪明的方法是让 RegExp 做更多的工作:
MATCH_LIST_ENTRY = /([^:]+):\s*((?:[^,]+(?:,\s*|$))+?)(?=[^:,]+:|$)/
def parse_list2(str)
str.scan(MATCH_LIST_ENTRY).map do |k, vs|
[k.to_sym, vs.split(/,\s*/)]
end.to_h
end
我不会为这个选择正则表达式,但它比看起来更简单。 Regexper does a pretty good job 解释一下。
您可以在 repl.it 上看到这两个操作:https://repl.it/@jrunning/LongtermMidnightblueAssembler