【问题标题】:replacing html tag and its content using ruby gsub使用 ruby​​ gsub 替换 html 标签及其内容
【发布时间】:2019-03-22 01:56:22
【问题描述】:

我正在尝试通过执行以下操作将 html 内容中的 <p>..</p> 标记内容替换为空字符串。

string =  \n <img alt=\"testing artice breaking news\" src=\"something.com" />\n <p>\n \tnew vision content for testing rss feeds\n </p>\n " 

当我这样做时

string.gsub!(/<p.*?>|<\/p>/, '')

它只是用空字符串替换了&lt;p&gt;&lt;/p&gt;,但内容仍然存在。如何删除标签及其内容?

【问题讨论】:

  • 必填:Do not parse HTML with regex。这可能适用于“快速而肮脏”的解决方案,但 正确的 方法是使用 HTML 解析器。 (例如 Nokogiri,用于红宝石。)
  • 请注意,尽管 Onigmo(Ruby 的正则表达式引擎)在 IMO 上比 PCRE 以外的任何其他正则表达式引擎都更强大,并且可以用它解析 XHTML,但 HTML 并不那么容易:&lt;p&gt;foo&lt;ul&gt;&lt;li&gt;quux&lt;/ul&gt;bar&lt;/p&gt;是有效的 HTML,我想不出一个可以做正确事情的正则表达式解决方案(删除 &lt;p&gt;foo&lt;/p&gt;,并单独留下 &lt;ul&gt;&lt;li&gt;quux&lt;/ul&gt;bar)。

标签: ruby


【解决方案1】:

显然,您的正则表达式与 &lt;p&gt;...&lt;/p&gt;&lt;p&gt; 及其内容)不匹配。试试这个:

string.gsub!(/&lt;p&gt;.*&lt;\/p&gt;/, '')

test = '\n <img alt=\"testing artice breaking news\" src=\"something.com" />\n <p>\n \tnew vision content for testing rss feeds\n </p>\n "'
test.gsub(/<p>.*<\/p>/, '')

返回

"\\n &lt;img alt=\\\"testing artice breaking news\\\" src=\\\"something.com\" /&gt;\\n \\n \""

另外,请考虑@Tom Lord 的评论,您可以使用Nokogiri 来操作HTML。

【讨论】:

  • string.gsub! 这返回 nil。没有bangstring.gsub 它返回相同的字符串。
  • @user3576036 您可以尝试使用示例,也可以编辑要替换的确切字符串
【解决方案2】:

首先,在解析HTML时考虑使用HTML解析器,见How do I remove a node with Nokogiri?

如果你想用正则表达式来做,你可以使用

string.gsub(/<p(?:\s[^>]*)?>.*?<\/p>/m, '')

请参阅Rubular regex demo这适用于无法嵌套的标签详情

  • &lt;p(?:\s[^&gt;]*)?&gt; - &lt;p,以及可选的空格序列和除&gt;之外的零个或多个字符(尽可能多),然后是&gt;
  • .*? - 由于 /m,任何零个或多个字符都尽可能少
  • &lt;\/p&gt; - &lt;/p&gt; 字符串。

如果标签可以嵌套,你仍然可以使用正则表达式:

tagname = "p"
rx = /<#{tagname}(?:\s[^>]*)?>(?:[^<]*(?:<(?!#{tagname}[\s>]|\/#{tagname}>)[^<]*)*|\g<0>)*<\/#{tagname}>/
p string.gsub(rx, '')
# => "\n <img alt=\"testing artice breaking news\" src=\"something.com\" />\n \n"

请参阅Rubular regex demo详情

  • &lt;#{tagname} - &lt; 和标签名称
  • (?:\s[^&gt;]*)?&gt; - 一个可选的空格序列,然后是 &lt; 以外的零个或多个字符
  • (?:[^&lt;]*(?:&lt;(?!#{tagname}[\s&gt;]|\/#{tagname}&gt;)[^&lt;]*)*|\g&lt;0&gt;)* - 零次或多次出现
    • (?:[^&lt;]*(?:&lt;(?!#{tagname}[\s&gt;]|\/#{tagname}&gt;)[^&lt;]*)* - 除&lt; 之外的零个或多个字符,然后是零个或多个&lt; 序列,后面不跟标签名称+ &gt; 或空格或/ + 标签名称+ &gt; 后跟零或除&lt; 字符以外的更多字符
    • |
    • \g&lt;0&gt; - 整个正则表达式模式递归
  • &lt;\/#{tagname}&gt; - &lt;/ + 标签名称 + &gt;

查看Ruby demo

string = "\n <img alt=\"testing artice breaking news\" src=\"something.com\" />\n <p>\n \tnew vision content for testing rss feeds\n </p>\n"
p string.gsub(/<p(?:\s[^>]*)?>.*?<\/p>/m, '')

tagname = "p"
rx = /<#{tagname}(?:\s[^>]*)?>(?:[^<]*(?:<(?!#{tagname}[\s>]|\/#{tagname}>)[^<]*)*|\g<0>)*<\/#{tagname}>/m
p string.gsub(rx, '')```
# => "\n <img alt=\"testing artice breaking news\" src=\"something.com\" />\n \n"

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 2011-11-03
    • 2020-11-11
    • 2010-12-03
    • 2022-12-08
    • 2013-12-07
    • 1970-01-01
    • 1970-01-01
    • 2019-05-27
    相关资源
    最近更新 更多