草庐IT

关于 ruby??:eval 文件中的某些正则表达式以替换字符串中的字符

codeneng 2023-03-28 原文

eval certain regex from file to replace chars in string

我是 ruby?? 新手,所以请原谅我的无知 :)

我刚刚了解了 eval 并且读到了它的阴暗面。

到目前为止我读过的内容:

  • Ruby 中的 eval 什么时候是合理的?

  • \\'eval\\' 应该是讨厌的吗?

  • Ruby Eval 和 Ruby 代码的执行

所以我要做的是读取一个文件,其中有一些文本,例如 /e/ 3 它将在评估后将每个 e 替换为 3

所以到目前为止我做了什么:(工作但是..)

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
/$/ !
/$/ !!

这只是因为我知道文件中行的长度。

所以假设我的文件具有以下 /a-z/ 3 我的程序将无法执行预期的操作。

笔记

我尝试使用 Regexp.new reg 并导致以下 /\\/e\\/3/ 在这种情况下不是很有帮助。

`Regexp

的简单示例

1
2
3
4
str="/e/3"
result="elt"
result=result.gsub(Regexp.new str)
p result #outputs: #<Enumerator:"elt":gsub(/\\/e\\/3/)>

我已经尝试去除斜线,但即使这不会提供所需的结果,因此 gsub() 需要两个参数,例如这个 gsub(/e/,"3").

关于 Regexp 的用法,我已经阅读 Convert a string to regular expression ruby??

  • 当你有 Regex.new 时你不需要 eval。我也远离命名您的输入文件 .rb 因为它肯定不是 Ruby 代码。为了使它与 Regexp.new 一起工作,首先去掉前导和尾随斜杠。
  • @tadman,这是我的错,我输入的是 rb 而不是 txt 抱歉。我编辑了帖子。无论如何,使用 regexp.new 没有帮助,因此我会给我不想要的结果,因为方法 gsub 需要两个参数,例如 gsub(/e/,"3")
  • 您可以控制输入文件的格式吗?如果是这样,你可以让你的生活轻松一百倍。
  • 好吧,虽然我可以完全控制这个文件,但格式是由分配者给出的。这不在桌面上,因此 test.txt 在测试时可能会更大:)。再次,即使我可以去掉反斜杠,我也必须将第二个参数提供给 gsub 方法


虽然您可以编写一些东西来解析该文件,但它很快就会变得复杂,因为您必须解析正则表达式。考虑 /\\/foo\\\\/.

有许多不完整的解决方案。您可以在空格上拆分,但这会在 /foo bar/.

上失败

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'] }
]

虽然老师可能指定了一个糟糕的格式,但对糟糕的要求提出回避是作为开发人员的好习惯。

  • 感谢您努力帮助人类。关于你的代码的小闲聊:作为一名学生和 ruby?? 初学者,我还没有使用过 JSON 库。但看看你的代码,我有点明白你答案的 JSON 部分发生了什么。所以,让我看看我是否明白这一点: 1.你会重写 test.txt 文件中的所有修改并将其放入不同格式的 JSON 文件中吗? 2.您会从txt中获取数据并将其放入哈希中然后遍历它吗?那么那些 [ {"re":"e","replace":"3" }, {"re":"l","replace":"1" } ] 写在哪里?
  • 无论如何,我会再次要求教授更好地了解他的意图,然后我可以看看这个答案是否是答案,但现在我非常感谢你的帮助和 1
  • @studentaccount4 是的,如果这是生产,我会将文件更改为 JSON。你可以像我一样手动翻译。或者,既然数据这么简单,就用正则表达式解析原始文件,放入合理的数据结构,用JSON.dump写成JSON。因为这是一项作业,所以是的,问问你的教授他们想让你做什么。


这是一个非常简单的例子,它使用 s/.../.../s/.../.../g 之类的 vi 表示法:

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"

这里的原则是您可以使用一个非常简单的正则表达式来解析您输入的正则表达式并将清理后的数据输入到 Regexp.new 中。这里绝对不需要 eval ,如果有任何严重限制你可以做的事情。

通过一些工作,您可以更改该正则表达式以解析现有文件中的内容并使其执行您想要的操作。

  • 好吧,这看起来很酷,我想我在这里得到了你想要完成的任务,但我有一个关于 _, 这是干什么用的小问题?!另外,看看你写的代码我有一个小问题,请原谅我的无知,spec.match 的返回值是如何在模式、repl 和 with 之间分布的?!请您这么好心,并详细解释 rsub() 的第二行中发生的事情,否则这应该会有所帮助:)
  • 在 Ruby 中,_ 是一个"不关心"变量。第一个元素无关紧要,它是所有匹配项的集合。至于解释,对你来说不能太简单,那里有很多事情要做,但如果你把它分解并在 irb 中尝试那行,它会更有意义。

有关关于 ruby??:eval 文件中的某些正则表达式以替换字符串中的字符的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  4. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  5. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  6. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  7. ruby-on-rails - rails : keeping DRY with ActiveRecord models that share similar complex attributes - 2

    这似乎应该有一个直截了当的答案,但在Google上花了很多时间,所以我找不到它。这可能是缺少正确关键字的情况。在我的RoR应用程序中,我有几个模型共享一种特定类型的字符串属性,该属性具有特殊验证和其他功能。我能想到的最接近的类似示例是表示URL的字符串。这会导致模型中出现大量重复(甚至单元测试中会出现更多重复),但我不确定如何让它更DRY。我能想到几个可能的方向...按照“validates_url_format_of”插件,但这只会让验证干给这个特殊的字符串它自己的模型,但这看起来很像重溶液为这个特殊的字符串创建一个ruby​​类,但是我如何得到ActiveRecord关联这个类模型

  8. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  9. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  10. ruby - 如何在 Ruby 中顺序创建 PI - 2

    出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits

随机推荐