Ruby on rails 轨道编号\u到\u百分比和子轨道行为
我正在尝试将较大的%数字替换为较短的版本(10000%->10k%)。通常代码可以工作,但如果使用了Ruby on rails 轨道编号\u到\u百分比和子轨道行为,ruby-on-rails,ruby,regex,Ruby On Rails,Ruby,Regex,我正在尝试将较大的%数字替换为较短的版本(10000%->10k%)。通常代码可以工作,但如果使用了number\u to\u percentage,它将停止工作(使用完全相同的字符串) 这是什么原因造成的?有什么想法吗?关键区别在于: "10000.000%".class #=> String number_to_percentage(10000).class # => ActiveSupport::SafeBuffer ActiveSupport::SafeBuffer是Str
number\u to\u percentage
,它将停止工作(使用完全相同的字符串)
这是什么原因造成的?有什么想法吗?关键区别在于:
"10000.000%".class #=> String
number_to_percentage(10000).class # => ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer
是String
的子类,包含不安全字符串方法的概念(包括sub
和gsub
)。这个概念对于rails视图(通常使用number\u to\u percentage
)在安全性方面非常有用;防止XSS漏洞
解决方法是将变量显式转换为字符串
:
number_to_percentage(10000).to_str.sub(/(\d\d)\d\d\d(?:[.,]\d+)?\%$/){ "#{$1}k%" }
=> "10k%"
(请注意,它是to_str
,而不是to_s
!to_s
只返回self
,即ActiveSupport::SafeBuffer
的实例;而to_str
返回常规字符串
)
,并对该问题进行更详细的说明
或者,您也可以这样编写代码,它可以按预期工作:
number_to_percentage(10000).sub(/(\d\d)\d\d\d(?:[.,]\d+)?%$/, '\1k%')
#=> "10k%"
实际上我更喜欢这种方法,因为您不再依赖于对(非线程安全)全局变量的修改。因为number\u to\u percentage返回的是ActiveSupport::SafeBuffer,而不是字符串
helper.number_to_percentage(10000).class # => ActiveSupport::SafeBuffer
ActiveSupport::SafeBuffer(String的一个子类)对sub这样的不安全方法有一些神奇的作用。这就是为什么你会有一些惊喜。你的Ruby和Rails版本是什么?它在Ruby 2.4.1p111和Rails 5.1.3中工作。@GregNavis你确定吗??我发现的一件事是,如果您先运行“10000.000%”。sub(…)
,然后设置$1
。所以,number\u to\u percentage(10000).sub(…)
如果您先运行第一个方法,它就会工作!ruby 2.3.1和rails 5.1.2良好的性能,@TomLord。这正是我所做的。谢谢,我也找到了使用\1的方法,但仍然很好奇为什么原始代码不起作用(但使用文字!)@valodzka。
helper.number_to_percentage(10000).class # => ActiveSupport::SafeBuffer