不带捕获组的 Ruby 字符串替换

Ruby string replace without capture group

提问人:elbrunovsky 提问时间:5/28/2023 最后编辑:elbrunovsky 更新时间:5/28/2023 访问量:78

问:

Ruby 的函数系列执行替换,并支持捕获组,即使是一个普通字符串(至少它似乎支持打印所有替换文本)。我不知道这是否是有意的,但如果是不安全的,例如,将变量作为 API 的输入。有没有替代的库函数可以用来执行字符串替换而没有这个缺点?或者某种逃脱方式.String.sub(pat, txt)txtpat\0pattxttxt

Ruby 字符串 替换

评论

4赞 mu is too short 5/28/2023
你有你遇到的问题的例子吗?
1赞 Cary Swoveland 5/28/2023
我不明白你说的“......支持捕获组,即使是一个普通的字符串......”。大概你的意思是一个字符串(这与“普通字符串”有什么不同?)而不是正则表达式。虽然正则表达式可能有捕获组,但我不明白字符串有它们的意思。txtpatpat
1赞 tadman 5/28/2023
小调,但很重要。 是一个直接调用的方法,但是一个被调用的方法,这就是你在这里的意思。String.subStringString#subString
0赞 Les Nightingill 5/28/2023
如果它是 Rails 应用(即使它不是!),你可以使用 ActionView::Helpers::SanitizeHelper#sanitize,可以按原样使用,也可以使用缓解应用中特定漏洞的选项

答:

2赞 Alex 5/28/2023 #1

你的意思是这样的:

>> "mytext".sub("text", " \\0 replaced by \\` \\0")
=> "my text replaced by my text"

您可以转义反斜杠:

>> "mytext".sub("text", " \\\\0 replaced")
=> "my \\0 replaced"

def b_esc(str) = str.gsub("\\", "\\\\\\\\")

>> "mytext".sub("text", b_esc(" \\0 replaced"))
=> "my \\0 replaced"

# how many backslashes?
>> "\\0".chars        #=> ["\\", "0"] # uhh.. yes
>> "\\0".bytes        #=> [92, 48]
#                      one ^ 
>> b_esc("\\0").bytes #=> [92, 92, 48]
#                      two ^   ^

或者使用块:

>> "mytext".sub("text") { " \\0 replaced" }
=> "my \\0 replaced"

或者也许 []=

>> t = "mytext"
=> "mytext"
>> t["text"] = " \\0 replaced"
=> " \\0 replaced"
>> t
=> "my \\0 replaced"

请注意,在字符串替换中,字符组合(如 )被视为普通文本,而不是特殊的匹配变量。但是,您可以使用以下组合引用一些特殊的匹配变量:$&

\&并对应于 ,其中包含完整的匹配文本。
对应于 ,它包含匹配后的字符串。
对应于 ,它包含 match 前的字符串。
对应于 ,其中包含最后一个捕获组。
\0$&\'$'\`$`\+$+

https://docs.ruby-lang.org/en/3.2/String.html#class-String-label-Substitution+Methods

0赞 elbrunovsky 5/28/2023 #2

就我而言,最终以 + 结尾,因为这个词总是以模式结尾。 如果不是这种情况,是我正在寻找的解决方案。indexinsert[]=

def prepend(txt, pat, word)
  index = txt.index(pat)
  return if index.nil?

  txt.insert(index, word)
  true
end