【问题标题】:How can I read a string into a Ruby dictionary?如何将字符串读入 Ruby 字典?
【发布时间】:2013-11-30 03:18:41
【问题描述】:

我目前想用 Jekyll-Blog 替换我的 Wordpress-Blog。为此,我必须找到 WordPress 标题标签的替代方法:

[caption id="attachment_76716" align="aligncenter" width="500"]<a href="http://martin-thoma.com/wp-content/uploads/2013/11/WER-calculation.png"><img src="http://martin-thoma.com/wp-content/uploads/2013/11/WER-calculation.png" alt="WER calculation" width="500" height="494" class="size-full wp-image-76716" /></a> WER calculation[/caption]

我认为如果我能在我的帖子中这样使用它们会很好:

{% caption align="aligncenter" width="500" alt="WER calculation" text="WER calculation" url="../images/2013/11/WER-calculation.png" %}

虽然它应该被渲染到:

<div style="width: 510px" class="wp-caption aligncenter">
    <a href="../images/2013/11/WER-calculation.png">
        <img src="../images/2013/11/WER-calculation.png" alt="WER calculation" width="500" height="494" class="size-full">
    </a>
    <p class="wp-caption-text">WER calculation</p>
</div>

所以我写了一些 python 代码来进行替换(一次),我想写一个 Ruby / Liquid / Jekyll 插件来进行渲染。但我不知道怎么读

align="aligncenter" width="500" alt="WER calculation" text="WER calculation" url="../images/2013/11/WER-calculation.png"

放入 ruby​​ 字典(它们似乎被称为“哈希”?)。

这是我的插件:

# Title: Caption tag
# Author: Martin Thoma, http://martin-thoma.com

module Jekyll
  class CaptionTag < Liquid::Tag

    def initialize(tag_name, text, tokens)
      super
      @text = text
      @tokens = tokens
    end

    def render(context)
        @hash = Hash.new
        @array = @text.split(" ")
        @array.each do |element|
            key, value = element.split("=")
            @hash[key] = value
        end
        #"#{@text} #{@tokens}"
        "<div style=\"width: #{@hash['width']}px\" class=\"#{@hash['alignment']}\">" +
        "<a href=\"../images/#{@hash['url']}\">" +
            "<img src=\"../images/#{@hash['url']}\" alt=\"#{@hash['text']}\" width=\"#{@hash['width']}\" height=\"#{@hash['height']}\" class=\"#{@hash['class']}\">" +
        "</a>" +
        "<p class=\"wp-caption-text\">#{@hash['text']}</p>" +
        "</div>"
    end
  end
end

Liquid::Template.register_tag('caption', Jekyll::CaptionTag)

在 Python 中,我会使用 CSV module 并将分隔符设置为空格,将引号字符设置为 "。但我是 Ruby 新手。

我刚刚看到 Ruby 也有一个 CSV 模块。但它不起作用,因为引用不正确。所以我需要一些 html 解析。

Python 解决方案

def parse(text):
    splitpoints = []

    # parse
    isOpen = False
    for i, char in enumerate(text):
        if char == '"':
            isOpen = not isOpen
        if char == " " and not isOpen:
            splitpoints.append(i)

    # build data structure
    dictionary = {}
    last = 0
    for i in splitpoints:
        key, value = text[last:i].split('=')
        last = i+1
        dictionary[key] = value[1:-1] # remove delimiter
    return dictionary

print(parse('align="aligncenter" width="500" alt="WER calculation" text="WER calculation" url="../images/2013/11/WER-calculation.png"'))

【问题讨论】:

  • 你可以用同样的方式使用Ruby的CSV类。或者你总是可以编写一个合适的解析器。
  • 我添加了一个可以在 Python 中实现预期的解决方案。但我是 Ruby 新手,请告诉我如何使用 Ruby 进行操作?

标签: ruby jekyll liquid


【解决方案1】:

如果您将行分隔符设置为空格,列分隔符设置为 '=' 并将引号字符设置为 '"',您可以使用 Ruby 的 CSV 类轻松地将字符串解析为 Hash:

require 'csv'

def parse_attrs(input)
  options = { col_sep: '=', row_sep: ' ', quote_char: '"' }
  csv = CSV.new input, options

  csv.each_with_object({}) do |row, attrs|
    attr, value = row
    value ||= true
    attrs[attr] = value
  end
end

例子:

irb(main):031:0> input = 'align="aligncenter" width="500" alt="WER calculation" text="WER calculation" url="../images/2013/11/WER-calculation.png" required'
=> "align=\"aligncenter\" width=\"500\" alt=\"WER calculation\" text=\"WER calculation\" url=\"../images/2013/11/WER-calculation.png\""
irb(main):032:0> parse_attrs input
=> {"align"=>"aligncenter", "width"=>"500", "alt"=>"WER calculation", "text"=>"WER calculation", "url"=>"../images/2013/11/WER-calculation.png"}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-17
    • 2021-12-15
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多