使用Regex的CRUD文本-Ruby

迷你约翰

我正在寻找解析和更新文档的解决方案。一个很好的例子是user.js脚本。

示例案例:

用户将user.js脚本上载到userscripts.org。该文件必须具有用于浏览器的特定变量的开头。例如:

// ==UserScript==
// @name        Fancy Title
// @description Fancey Description
// @namespace   http://example.com
// @icon        http://example.com/icon.png
// @updateURL   http://example.com/user.js
// @downloadURL http://example.com/user.js
// @homepageURL http://example.com
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @include     http*://example.com
// @include     http://example.com/scripts/*
// @include     http://example.com/tags/*
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @version     1.0
// ==/UserScript==

将这些变量和/modifyadd它们复查到文档中将是一个好的解决方案基本上从@testing.title=>导入变量,@name Fancy Title反之亦然。

假设如果Meta Head不含变量@udpateURL@downloadeURL,我将分别添加它们。

我的第一个猜测是使用regex扫描文档(@\w+),这将为我获取所有变量,@但从那里我迷失了:)

我可以用普通红宝石解决此问题,还是可以使用方便的宝石?

编辑:

山姆指出:\/\/\s*@(\w+)\s+(.*)这恰好捕获了我需要的变量。

标识符(@title)和值(Fancy Title)。

如何设置,阅读或更新它们?


@MrYoshiji为我提供了一个非常出色的regex Meta Reader:

raw_metas = file_content.scan( /\A\/\/\s==UserScript==(\w|\W)*\/\/\s==\/UserScript==/ )
metas = {}
raw_metas.split(/\r\n|\n|\r/).each do |line_with_meta|
  attribute_name = line_with_data.scan(/@\w+/)
  value = line_with_data.sub("// #{attribute_name}", '').strip
  if metas[attribute_name.sub('@', '').to_sym].present?
    metas[attribute_name.sub('@', '').to_sym] = [ metas[attribute_name.sub('@', '').to_sym], value].flatten
  else
    metas[attribute_name.sub('@', '').to_sym] = value
  end
end

但是我完全不知道如何设置它以与模型的属性进行交互。


我需要更改哪些元数据

这意味着那些属性(:description等)存储在我的模型中,我需要传递它们。

// @name => @model.name


// @description => @model.description
// @namespace   => Application root_path

// @updateURL   => @model show_view url
// @downloadURL => @Model show_view url
// @homepageURL => Application root_path

// @include     => Custom url (passed by me)
// @include     => Custom url (passed by me)
// @include     => Custom url (passed by me)

// @version     => @model.version
zx81

[编辑:在聊天中,您提到您的输入可能在一行上。第二个演示显示了一个正则表达式来处理这一点,也是一般程序重建的字符串。]

此代码存储在两个散列的名称和值,替换@version2.0,然后对其进行输出(见在底部的输出在线演示):

subject = <<-eos
@name        Fancy Title
// @description Fancey Description
// @namespace   http://example.com
// @icon        http://example.com/icon.png
// @updateURL   http://example.com/user.js
// @downloadURL http://example.com/user.js
// @homepageURL http://example.com
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js
// @include     http*://example.com
// @include     http://example.com/scripts/*
// @include     http://example.com/tags/*
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_listValues
// @version     1.0
eos

regex = /\/\/ (@\w+)\s*([^\n]*)/

# put captures in two hashes
tokens = Hash.new
values = Hash.new
counter = 0
subject.scan(regex) {|m|
    tokens[counter] = $1
    values[counter] = $2
    counter += 1
}

# find hash key for @version
versionkey = tokens.index("@version")
# change version to 2.0
values[versionkey] = "2.0"

# print names and values
i=0
while i < counter  do
   puts "#{tokens[i]} : #{values[i]}"
   i +=1
end

关键是令牌名称被捕获到组1,令牌值被捕获到组2(请参见下面的正则表达式说明)。我们使用这两个组中的值构建散列。

要操纵值,您有几种选择:

  1. 使用regex与gsub替换字符串中的行(不建议)

  2. 如演示中所示,直接操作哈希值中的值,将@version其更改为2.0,然后根据需要重建字符串。那就是我会做的。

解释正则表达式

//                       # '// '
(                        # group and capture to \1:
  @                      #   '@'
  \w+                    #   word characters (a-z, A-Z, 0-9, _) (1 or
                         #   more times (matching the most amount
                         #   possible))
)                        # end of \1
\s*                      # whitespace (\n, \r, \t, \f, and " ") (0 or
                         # more times (matching the most amount
                         # possible))
(                        # group and capture to \2:
  [^\n]*                 #   any character except: '\n' (newline) (0
                         #   or more times (matching the most amount
                         #   possible))
)                        # end of \2

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章