【问题标题】:gsub 正则表达式仅在字符串开头或有空格时匹配
【发布时间】:2022-01-22 12:10:50
【问题描述】:

我有一堆缺少撇号的短语,并且我有一系列修复,如下所示:

phrase = "i d let some"

def contractions_to_fix
  [
    { missing: "let s", fixed: "let's" }, 
    { missing: "i d", fixed: "i'd" }
  ]
end

我正在尝试遍历收缩数组以替换它们,如下所示:

contractions_to_fix.each do |contraction|
  if phrase.include? contraction[:missing]
    idea_title.gsub! contraction[:missing], contraction[:fixed]
  end
end

本例的目标是返回"i'd let some";但是,到目前为止,我尝试过的每个正则表达式都会返回错误的响应。

例如:

  • contraction[:missing] 导致 "i'd let'some
  • /\bcontraction[:missing]\b/ 导致 "i d let some"

任何帮助将不胜感激!

【问题讨论】:

  • contraction[:missing] 的计算结果不是正则表达式,而是一个字符串。

标签: ruby-on-rails regex ruby gsub


【解决方案1】:
arr = [
  { missing: "let s", fixed: "let's" }, 
  { missing: "i d", fixed: "i'd" }
]
h = arr.reduce({}) { |h,g| h.merge(g[:missing]=>g[:fixed]) }
  #=> {"let s"=>"let's", "i d"=>"i'd"}

r = /\b(?:#{h.keys.join('|')})\b/
  #=> /\b(?:let s|i d)\b/

"i d want to let some".gsub(r, h)
  #=> "i'd want to let some"

这使用String.gsub 的(第二种)形式,它将哈希作为第二个参数并且没有块。

也可以按如下方式计算h

h = arr.map { |g| g.values_at(:missing, :fixed) }.to_h
  #=> {"let s"=>"let's", "i d"=>"i'd"}

【讨论】:

    【解决方案2】:

    在标题中编写确切要求的最简单方法是将条件翻转:“前面或后面都没有非空格”:

    idea_title.gsub!(/(?<!\S)#{Regexp.escape(contraction[:missing])}(?!\S)/, contraction[:fixed])
    

    虽然/\b#{...}\b/ 应该适用于您给出的示例。您的问题可能是您将String 作为模式输入gsub! 而不是Regexp,因此您实际上是在寻找\b(反斜杠和小写B),而不是单词边界。试试吧

    idea_title.gsub!(/\b#{Regexp.escape(contraction[:missing])}\b/, contraction[:fixed])
    

    【讨论】:

    • 这行得通!太感谢了!如果有人有任何其他建议,我仍然会全力以赴,但很高兴至少有一种可行的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2012-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-15
    • 2017-12-25
    • 2021-07-04
    相关资源
    最近更新 更多