【问题标题】:How to replace multiple characters in string with special characters如何用特殊字符替换字符串中的多个字符
【发布时间】:2019-07-27 07:21:50
【问题描述】:

我有一个与“Ruby gsub multiple characters in string”几乎相同的问题。

但是,我的字符串包含特殊字符:

a = "<p>text</p> <strong>bold</strong> and <em>italic</em>"

使用/\w+/ 对我不起作用。 我尝试了许多不同的组合,但没有运气。 我应该在下面输入什么正则表达式匹配才能使其工作?我想替换字符串中的任何匹配项。

顺便说一句,我正在使用 Rails。

我想要的匹配是:

a.gsub({{WHAT REGEX EXP?}},
  "\r\n" => "",
  "<p>" => "",
  "</p>" => "\n\n",
  "<br />" => "\n",
  "<strong>" => "*",
  "</strong>" => "*",
  "<em>" => "_",
  "</em>" => "_",
  "<s>" => "~",
  "</s>" => "~",
  "<blockquote>" => ">",
  "</blockquote>" => ">",
  "&" => "&amp;",
  "<" => "&lt;",
  ">" => "&gt;"
)

【问题讨论】:

  • 看起来更像this一个。
  • @SebastianPalma,根据您的链接,您不能使用 gsub 进行多次替换,但可以。如果您查看我提供的链接,它会进行多次替换,但正则表达式仅处理字符。我只需要处理任何字符。
  • 如果任一答案有帮助,请选择对您最有帮助的答案。

标签: regex ruby


【解决方案1】:

#gsub 工作:

replacements = {
  "\r\n" => "",
  "<p>" => "",
  "</p>" => "\n\n",
  "<br />" => "\n",
  "<strong>" => "*",
  "</strong>" => "*",
  "<em>" => "_",
  "</em>" => "_",
  "<s>" => "~",
  "</s>" => "~",
  "<blockquote>" => ">",
  "</blockquote>" => ">",
  "&" => "&amp;",
  "<" => "&lt;",
  ">" => "&gt;"
}

a = "<p>text</p> <strong>bold</strong> and <em>italic</em>"

replacements.each do |find, replace|
  a.gsub!(find, replace)
end

a # => "text\n\n *bold* and _italic_"

【讨论】:

  • 感谢 Philipe,这可行,但我正在寻找一种方法,只需一个 gsub 调用即可。我相信我只是缺少正确的正则表达式。
  • 为什么?这比正则表达式更简单、可能更快且更易于维护。
  • 很有可能。老实说,两个答案都是正确的,而且您的答案确实更容易维护。因此,我将接受您的“可能重复”作为解决方案,并向将来阅读此内容的人提及这里的两个答案都是可以接受的。再次感谢。
  • 同意,这可能快很多。字符串搜索比非锚定模式快得多。
【解决方案2】:

一气呵成:

replacements = {
  "\r\n" => "",
  "<p>" => "",
  "</p>" => "\n\n",
  "<br />" => "\n",
  "<strong>" => "*",
  "</strong>" => "*",
  "<em>" => "_",
  "</em>" => "_",
  "<s>" => "~",
  "</s>" => "~",
  "<blockquote>" => ">",
  "</blockquote>" => ">",
  "&" => "&amp;",
  "<" => "&lt;",
  ">" => "&gt;"
}

keys = Regexp.union(replacements.keys)
a    = "<p>text</p> <strong>bold</strong> and <em>italic</em>"

p a.gsub(keys, replacements) # => "text\n\n *bold* and _italic_"

这很容易,因为Regexp.union 为您完成了所有艰苦的工作(逃避奇怪的字符)。

【讨论】:

【解决方案3】:

你可以通过一个电话来完成,正则表达式是/&lt;[^&gt;]+&gt;|[&lt;&gt;&amp;]/

a = "<p>text</p> <strong>bold</strong> and <em>italic</em> & <>"
a.gsub(/(<[^>]+>|[<>&])/, replacements)
# => "text\n\n *bold* and _italic_ &amp; &lt;&gt;"

Demo

String#gsub(pattern, hash) → new_str 如果第二个参数是 Hash,并且匹配的文本是它的键之一,则对应的值是替换字符串。 Docs

正则表达式解释:

  • &lt;[^&gt;]+&gt; 匹配 HTML 标记 - 您首先匹配 &lt;,然后是一个或多个不是 &gt; 的字符与 [^&gt;]+,然后是 &gt;
  • [&lt;&gt;&amp;] 匹配特殊字符的特殊单次出现,例如 &lt;&gt;&amp;

也就是说,正则表达式并不是处理 HTML 的最佳工具,最好使用 HTML 解析器(例如 Nokogiri)。

【讨论】:

  • Mrzasa,这行得通,谢谢你的详细解释。我相信你写“then > * [&]”应该是“then > | [&]”时有一个错误,对吧?您将如何使用 nokogiri 进行上述操作?它会更清洁吗?它会运行得更快并且需要更少的资源吗?会有什么好处?再次感谢。
  • 我搞砸了列表格式,已修复。谢谢@Ben :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 2014-12-07
相关资源
最近更新 更多