eval certain regex from file to replace chars in string
我是 ruby?? 新手,所以请原谅我的无知 :)
我刚刚了解了
到目前为止我读过的内容:
-
Ruby 中的
eval 什么时候是合理的? -
\\'eval\\' 应该是讨厌的吗?
-
Ruby Eval 和 Ruby 代码的执行
所以我要做的是读取一个文件,其中有一些文本,例如
所以到目前为止我做了什么:(工作但是..)
1 2 3 4 5 6 7 8 9 | def evaluate_lines result="elt" IO.foreach("test.txt") do |reg| reg=reg.chomp.delete(' ') puts reg result=result.gsub(eval(reg[0..2]),"#{reg[3..reg.length]}" ) p result end end |
test.txt 文件的内容
1 2 3 4 5 | /e/ 3 /l/ 1 /t/ 7 /$/ ! /$/ !! |
这只是因为我知道文件中行的长度。
所以假设我的文件具有以下
笔记
我尝试使用
`Regexp
的简单示例
1 2 3 4 | str="/e/3" result="elt" result=result.gsub(Regexp.new str) p result #outputs: #<Enumerator:"elt":gsub(/\\/e\\/3/)> |
我已经尝试去除斜线,但即使这不会提供所需的结果,因此
关于 Regexp 的用法,我已经阅读 Convert a string to regular expression ruby??
虽然您可以编写一些东西来解析该文件,但它很快就会变得复杂,因为您必须解析正则表达式。考虑
有许多不完整的解决方案。您可以在空格上拆分,但这会在
上失败
1 | re, replace = line.split(/\\s+/, 2) |
您可以使用正则表达式。这是第一次刺伤。
1 | match ="/3/ 4".match(%r{^/(.*)/\\s+(.+)}) |
这在转义
1 | match = '/3\\// 4'.match(%r{\\A / ((?:[^/]|\\\\/)*) / \\s+ (.+)}x) |
我猜你老师的意图不是让你解析正则表达式。出于分配的目的,在空格上拆分可能没问题。你应该和你的老师澄清一下。
这是一种糟糕的数据格式。它是非标准的,难以解析,并且在替换上有限制。即使是制表符分隔的文件也会更好。
现在几乎没有理由使用非标准格式。最简单的事情是为文件使用标准数据格式。 YAML 或 JSON 是最明显的选择。对于这样简单的数据,我建议使用 JSON.
1 2 3 4 | [ {"re":"e","replace":"3" }, {"re":"l","replace":"1" } ] |
解析文件很简单,使用内置的 JSON 库。
1 2 | require 'json' specs = JSON.load("test.json") |
然后您可以将它们用作哈希列表。
1 2 3 4 5 6 7 | specs.each do |spec| # No eval necessary. re = Regexp.new(spec["re"]) # `gsub!` replaces in place result.gsub!(re, spec["replace"]) end |
数据文件是可扩展的。例如,如果稍后您想添加正则表达式选项。
1 2 3 4 | [ {"re":"e","replace":"3" }, {"re":"l","replace":"1","options": ['IGNORECASE'] } ] |
虽然老师可能指定了一个糟糕的格式,但对糟糕的要求提出回避是作为开发人员的好习惯。
这是一个非常简单的例子,它使用
1 2 3 4 5 6 7 8 9 10 11 12 | def rsub(text, spec) _, mode, repl, with, flags = spec.match(%r[\\A(.)\\/((?:[^/]|\\\\/)*)/((?:[^/]|\\\\/)*)/(\\w*)\\z]).to_a case (mode) when 's' if (flags.include?('g')) text.gsub(Regexp.new(repl), with) else text.sub(Regexp.new(repl), with) end end end |
请注意,匹配器会查找非斜线字符 (
你可以在哪里得到这样的结果:
1 2 3 4 5 6 7 8 9 10 11 | rsub('sandwich', 's/and/or/') # =>"sorwich" rsub('and/or', 's/\\//,/') # =>"and,or" rsub('stack overflow', 's/o/O/') # =>"stack Overflow" rsub('stack overflow', 's/o/O/g') # =>"stack OverflOw" |
这里的原则是您可以使用一个非常简单的正则表达式来解析您输入的正则表达式并将清理后的数据输入到
通过一些工作,您可以更改该正则表达式以解析现有文件中的内容并使其执行您想要的操作。