评估没有字符串插值的字符串 [英] Eval a string without string interpolation

查看:71
本文介绍了评估没有字符串插值的字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AKA如何使用正则表达式查找未转义的字符序列?

给出一个设置有以下内容的环境:

Given an environment set up with:

@secret = "OH NO!"
$secret = "OH NO!"
@@secret = "OH NO!"

并从看起来像这样的文件中读取给定的字符串:

and given string read in from a file that looks like this:

some_str = '"\"#{:NOT&&:very}\" bad. \u262E\n#@secret \\#$secret \\\\#@@secret"'

我想将其评估为Ruby字符串,但不进行插值。因此,结果应为:

I want to evaluate this as a Ruby string, but without interpolation. Thus, the result should be:

puts safe_eval(some_str)
#=> "#{:NOT&&:very}" bad. ☮
#=> #@secret #$secret \#@@secret

相比之下,仅评估的解决方案会产生

By contrast, the eval-only solution produces

puts eval(some_str)
#=> "very" bad. ☮
#=> OH NO! #$secret \OH NO!






起初我尝试过:


At first I tried:

def safe_eval(str)
  eval str.gsub(/#(?=[{@$])/,'\\#')
end

但这在上面的恶意中间情况下失败,产生:

but this fails in the malicious middle case above, producing:

#=> "#{:NOT&&:very}" bad. ☮
#=> #@secret \OH NO! \#@@secret


推荐答案

您可以通过通过确保要转义的字符前面有偶数个反斜杠来进行正则表达式:

You can do this via regex by ensuring that there are an even number of backslashes before the character you want to escape:

def safe_eval(str)
  eval str.gsub( /([^\\](?:\\\\)*)#(?=[{@$])/, '\1\#' )
end

…其中表示:

…which says:


  • 查找不是反斜杠的字符 [^ \\]

  • 后跟两个反斜杠(?: \)

    • 重复零次或多次 *

    • Find a character that is not a backslash [^\\]
    • followed by two backslashes (?:\\\\)
      • repeated zero or more times *

      • 非反斜杠,可能跟着反斜杠的偶数个

      • 然后是反斜杠,然后是

      • the non-backslash-maybe-followed-by-even-number-of-backslashes
      • and then a backslash and then a #

      这篇关于评估没有字符串插值的字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆