【问题标题】:Ruby - Strip all HTML tags from string with RegexRuby - 使用正则表达式从字符串中剥离所有 HTML 标记
【发布时间】:2017-12-21 15:34:05
【问题描述】:

我以下面的字符串为例

"<p>Hello,</p><p><br></p><p>my name is Same</p><p><br></p><p><br></p><p>Farewell,</p><p>Same</p>"

我想从中删除所有 HTML 标记。我正在使用以下哪种方法有效

Nokogiri::HTML(CGI.unescapeHTML(@message_preview)).content

但它最终产生了,

"Hello,my name is SameFarewell,Same"

当我想要的时候

"Hello, my name is Same Farewell, Same"

注意空格,给定一个换行符,我希望它的位置有一个空格,而不是字符串中的下一个字符。

我希望尝试使用 gsub 或 regex,但对如何实现它有点迷茫。

【问题讨论】:

  • 我想最简单的解决方案可能是在删除 HTML 标签之前用空格替换所有换行符&lt;br&gt;!?还可以将多个空格修剪为一个空格(如果有多个换行符)。
  • 其实,是的。你说的对。我最终使用了@message_preview.gsub!(/&lt;br&gt;/, ' '),但我刚刚意识到,由于键盘选项,我需要考虑大量的 html 标签。粗体、斜体、下划线、ol、ul、引号等。所以我需要找到一种方法将所有这些都包含在我的 gsub 中,然后运行 ​​nokogiri
  • @xander 你猜错了;使用这种方法,您迟早会发现自己在正则表达式上实现 HTML 解析器。
  • 您使用像 nokogiri 这样的解析器以正确的方式处理它,将其作为正则表达式是一个坏主意
  • 这是为什么呢?正则表达式优于 nokogiri 有什么缺点?

标签: ruby-on-rails ruby regex format gsub


【解决方案1】:

您可以在此处使用split 传递适用于您的示例的正则表达式(s 是您的字符串)。

def wordy s
  s.split(/\<.*?\>/)
   .map(&:strip)
   .reject(&:empty?)
   .join(' ')
   .gsub(/\s,/,',')
end

s = "<p>Hello,</p><p><br></p><p>my name is Same</p><p><br></p><p><br></p><p>Farewell,</p><p>Same</p>"
t = "<p>Hello <strong>Jim</strong>,</p><p> </p><p>This is <em>Charlie</em> and<u> I wanted to say</u></p><ol><li>hello</li><li>goodby</li></ol><p> </p><p>Farewell,</p><p>Lawrence</p>"

p wordy s
#"Hello, my name is Same Farewell, Same"

p wordy t
#"Hello Jim, This is Charlie and I wanted to say hello goodby Farewell, Lawrence"

【讨论】:

  • 嘿,这可行!在这个问题之前我正在使用 split 。我只是注意到我现在需要考虑许多其他文本选项。 &lt;ol&gt;, &lt;ul&gt;, bold, italics, underline, quotes 等。是否可以在您提供的这个正则表达式示例中包含这些内容?如果是这样,请介意为我修改它,这让我很困惑!
  • 我收回它,它有点工作。我有这个新的示例字符串,其中包含我讨论过的内容,"&lt;p&gt;Hello &lt;strong&gt;Jim&lt;/strong&gt;,&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;This is &lt;em&gt;Charlie&lt;/em&gt; and&lt;u&gt; I wanted to say&lt;/u&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;hello&lt;/li&gt;&lt;li&gt;goodby&lt;/li&gt;&lt;/ol&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Farewell,&lt;/p&gt;&lt;p&gt;Lawrence&lt;/p&gt;" 使用你的方法,我得到了这个"Hello Jim , This is Charlie and I wanted to say hello goodby Farewell, Lawrence"。我怎样才能去掉那些多余的空间?也许做一个检查以确保最多只有 1 个空格并且没有连续的空格?
  • 就是这样!非常感谢萨加尔!
  • @vin_Bin87 再次重构了答案。我同意其他人的观点,即您应该使用专用库而不是正则表达式。这些库已经过试验和测试,而正则表达式可能会破坏并且不适用于边缘示例。
  • 嘿,它实际上在结果输出中包含了这个&amp;nbsp;..."Hello&amp;nbsp; Jim, This is&amp;nbsp; Daniel . 知道如何解决这个问题吗?
【解决方案2】:

不幸的是,Nokogiri::XML::Node#traverse 在没有给出块时不会返回枚举数,这就是为什么我们需要这个丑陋的技巧来预先定义一个局部变量。

require 'nokogiri'

result, input = [], "<p>Hello,</p><p><br></p><p>my name is Same</p>" \
                    "<p><br></p><p><br></p><p>Farewell,</p><p>Same</p>"
Nokogiri::HTML(CGI.unescapeHTML(input)).traverse do |e|
  result << e.text if e.text?
end
result.join(' ')
#⇒ "Hello, my name is Same Farewell, Same"

【讨论】:

    【解决方案3】:

    我的决定:

    description.gsub!(/<("[^"]*"|'[^']*'|[^'">])*>/, ' ').strip
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多