AKA 如何使用正则表达式查找未转义的字符序列?
给定一个环境设置:
@secret = "OH NO!"
$secret = "OH NO!"
@@secret = "OH NO!"
并从文件中读取给定的字符串,如下所示:
some_str = '"\"#{:NOT&&:very}\" bad. \u262E\n#@secret \\#$secret \\\\#@@secret"'
我想将其作为 Ruby 字符串进行计算,但不进行插值。因此,结果应该是:
puts safe_eval(some_str)
#=> "#{:NOT&&:very}" bad. ☮
#=> #@secret #$secret \#@@secret
相比之下,仅eval
解决方案会产生
puts eval(some_str)
#=> "very" bad. ☮
#=> OH NO! #$secret \OH NO!
一开始我尝试过:
def safe_eval(str)
eval str.gsub(/#(?=[{@$])/,'\\#')
end
但是在上面的恶意中间情况下这会失败,产生:
#=> "#{:NOT&&:very}" bad. ☮
#=> #@secret \OH NO! \#@@secret
最佳答案
您可以通过正则表达式来完成此操作,方法是确保要转义的字符之前有偶数个反斜杠:
def safe_eval(str)
eval str.gsub( /([^\\](?:\\\\)*)#(?=[{@$])/, '\1\#' )
end
...上面写着:
- 查找不是反斜杠的字符
[^\\]
- 后跟两个反斜杠
(?:\\\\)
- 重复零次或多次
*
- 重复零次或多次
- 后跟文字
#
字符 - 并确保之后您可以看到
{
、@
或$
字符。 - 并将其替换为
- 非反斜杠后可能跟随偶数个反斜杠
- 然后是反斜杠,然后是
#
关于ruby - 评估不带字符串插值的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16695890/