Ruby:如何将指定格式字符串转换为含指定关键字的Hash
字符串转Hash的正则匹配解决方案
你的问题出在正则的贪婪匹配上,.*会尽可能匹配最多的字符,导致第一个匹配就把后面所有内容都吞掉了。下面提供两种可行的解决方法:
方法一:改进正则表达式(推荐)
使用非贪婪匹配结合正向预查,精准界定每个键值对的边界:
s = "Sub-attr:IVerb-attr:was born Object-attr:on theDate-attr:2022-01-01" # 正则解释: # (Sub-attr|Verb-attr|Object-attr|Date-attr): 匹配属性键 # (.*?) 非贪婪匹配值,直到遇到下一个属性键或字符串结尾 # (?=(?:Sub-attr|Verb-attr|Object-attr|Date-attr):|$) 正向预查,判断终止条件 matches = s.scan(/(Sub-attr|Verb-attr|Object-attr|Date-attr):(.*?)(?=(?:Sub-attr|Verb-attr|Object-attr|Date-attr):|$)/) # 转换为Hash result_hash = matches.each_with_object({}) do |(key, value), hash| hash[key.to_sym] = value.strip # 去除值前后多余空格 end puts result_hash.inspect # 输出:{:Sub-attr=>"I", :Verb-attr=>"was born", :Object-attr=>"on the", :Date-attr=>"2022-01-01"}
方法二:先分割再处理
通过正向预查分割字符串,再逐个处理每个键值对:
s = "Sub-attr:IVerb-attr:was born Object-attr:on theDate-attr:2022-01-01" # 按属性键开头分割,过滤空字符串 parts = s.split(/(?=(?:Sub-attr|Verb-attr|Object-attr|Date-attr):)/).reject(&:empty?) result_hash = parts.each_with_object({}) do |part, hash| # 按冒号分割为键和值,限制分割次数为2 key, value = part.split(':', 2) hash[key.to_sym] = value.strip end puts result_hash.inspect # 输出同上
两种方法都能准确得到你需要的Hash结构,核心是避免贪婪匹配,明确每个值的终止边界。
内容的提问来源于stack exchange,提问作者Tibo
相关产品推荐
相关产品推荐

