我在使用以下简化示例时遇到了这个问题:
line = searchstring.dup
line.gsub!(Regexp.escape(searchstring)) { '' }
我的理解是,对于存储在searchstring``String
,gsub!
将导致line
之后为空。实际上,这是许多字符串的情况,但不是这个情况:
searchstring = "D "
line = searchstring.dup
line.gsub!(Regexp.escape(searchstring)) { '' }
p line
结果是,line
之后被打印为"D "
,即没有执行替换。
任何包含空格的searchstring
都会发生这种情况。
p(Regexp.escape(searchstring))
对于我的例子,我看到输出了"D\\ "
,而我本希望得到的是"D "
。这是Ruby核心库中的一个bug,还是我误用了escape
函数?
一些背景:在我的具体应用程序中,这个简化的示例就是从这里派生出来的,我只想在一个长字符串中进行文字字符串替换,方法如下:
REPLACEMENTS.each do
|from, to|
line.chomp!
line.gsub!(Regexp.escape(from)) { to }
end
。我使用Regexp.escape
只是作为一种安全措施,以防被替换的字符串包含一些正则表达式元字符。
我使用的是MRI Ruby 2.6.4的Cygwin端口。
2条答案
按热度按时间vddsk6oq1#
我的理解是,对于存储在searchstring中的每一个String,gsub!将导致该行后来为空。
你的理解不正确,文件中的保证是
对于任何字符串,
Regexp.new(Regexp.escape(str))=~str
都将为真。对于您的示例,这确实成立
因此,您的代码应该如下所示
至于为什么会出现这种情况,* 曾经 * 有一个bug,其中
Regex.escape
会错误地处理空格字符:我猜他们试图通过将
's'
替换为' '
来尽可能地简化fix。从技术上讲,这确实添加了一个不必要的转义符,但这并没有破坏该方法的预期用途。b4lqfgs42#
任何包含空格的
searchstring
都会发生这种情况。实际上,如果我对于我的例子,我看到输出的是
"D\\ "
,而我希望得到的是"D "
。这是Ruby核心库中的bug,还是我误用了escape
函数?这看起来是一个bug。在我看来,空格不是
Regexp
meta字符,没有必要转义它。一些背景:在我的具体应用程序中,这个简化的例子就是从这里派生出来的,我只想在一个长字符串[...]中进行文字字符串替换。
如果你想进行字符串替换,那么不要使用
Regexp
,只使用一个字符串: