匹配属性列表有或没有引号

时间:2011-09-24 01:21:45

标签: ruby regex

我正在尝试匹配可能在其值周围引用的属性列表,如下所示:

aaa=bbb ccc="ddd" eee=fff

我想要的是没有引号的键/值列表。

'aaa' => 'bbb', 'ccc' => 'ddd', 'eee' => 'fff'

代码(ruby)现在看起来像这样:

attrs = {}
str.scan(/(\w+)=(".*?"|\S+)/).each do |k,v|
  attrs[k] = v.sub(/^"(.*)"$/, '\1')
end

我不知道是否可以通过使用正则表达式来删除引号。

有什么想法吗? 谢谢!

3 个答案:

答案 0 :(得分:1)

尝试使用管道获取可能的属性模式,EQUALS, QUOTE, NO-QUOTE, QUOTEEQUALS, NO-WHITESPACE

str.scan(/(\w+)=("[^"]+"|\S+)/).each do |k, v|
  puts "#{k}=#{v}"
end

测试。

编辑|嗯,好吧,我放弃了纯粹的'正则表达式解决方案(无论如何都将允许引号内的空格)。但你可以这样做:

attrs = {}

str.scan(/(\w+)=(?:(\w+)|"([^"]+)")/).each do |key, v_word, v_quot|
  attrs[key] = v_word || v_quot
end

这里的关键是抓住两个选择,并利用不匹配的事实将是零。

如果您想允许=周围的空格,只需在其两侧添加\s*

答案 1 :(得分:0)

我能够摆脱正则表达式中的引号,但前提是我也匹配引号。

s = "aaa=bbb ccc=\"ddd\" eee=fff"
s.scan(/([^=]*)=(["]*)([^" ]*)(["]*)[ ]*/).each {|k, _, v, _ | puts "key=#{k} value=#{v}" }

输出是:

key=aaa value=bbb
key=ccc value=ddd
key=eee value=fff

(匹配不=)=(匹配0或更多“)(匹配不是”或空格“(匹配0或更多”)零个或多个空格 然后忽略处理中的引用匹配。

我尝试了许多与OR的组合,但无法使运算符优先级和匹配正常工作。

答案 2 :(得分:0)

我不知道ruby,但是像([^ =]*)="?((?<=")[^"]*|[^ ]*)"?这样的东西可以工作吗?