【问题标题】:Ruby Regex to find iframes that do not have Youtube, Vimeo or Soundcloud in src?Ruby Regex 在 src 中查找没有 Youtube、Vimeo 或 Soundcloud 的 iframe?
【发布时间】:2014-10-27 07:04:18
【问题描述】:

我想编写一个正则表达式来忽略包含来自 youtube、vimeo 或 soundcloud 的 URL 的 iframe,这些 URL 是用 HTML 实体编码的字符串。

这是我尝试过的,但不起作用。下面给出了一些示例文本

正则表达式

<iframe(^?youtube|soundcloud|vimeo)*\/iframe

示例文本

<p><iframe src="http://www.3you3tube.com/embed/YoX1yc92MOU" width="500" height="300" frameborder="0" scrolling="auto"></iframe></p>
29  <p>text daily to place domain staff as volunteers with charity partners, we know all too well that the "V" word can sometimes be misunderstood. Occasionally seen as a dusty, worthy word, it can conjure images of coffee mornings and bric-a-brac stalls. So its not always as easy as you might think to get people to embrace their inner-volunteer. That's why the <a href="http://www.domain.co.uk/sdfn/2010/11/connect-create-domain-volunteers.shtml">Conne

样本输出

<iframe src="http://www.3you3tube.com/embed/YoX1yc92MOU" width="500" height="300" frameborder="0" scrolling="auto"></iframe>

示例文本

<p><iframe src="http://www.youtube.com/embed/YoX1yc92MOU" width="500" height="300" frameborder="0" scrolling="auto"></iframe></p>
29  <p>text daily to place domain staff as volunteers with charity partners, we know all too well that the "V" word can sometimes be misunderstood. Occasionally seen as a dusty, worthy word, it can conjure images of coffee mornings and bric-a-brac stalls. So its not always as easy as you might think to get people to embrace their inner-volunteer. That's why the <a href="http://www.domain.co.uk/sdfn/2010/11/connect-create-domain-volunteers.shtml">Conne

样本输出

nil

要明确一点:

我想忽略其中包含 youtube、vimeo 或 soundcloud 的 iframe。

我正在用 rubular 测试它 http://rubular.com/r/F9x6SSkIfu

【问题讨论】:

  • 这不是正则表达式的好用法。 HTML 变化太大,无法处理一个模式。相反,将实体解码回 HTML,然后使用解析器,例如 Nokogiri,它将规范化 HTML,从而很容易忽略顺序、空格、大写等方面的差异。
  • 我试过你提到的解决方案,看起来数据不是很一致。有几个损坏的标签导致 nokogiri 无法正确解析 HTML 字符串。一个例子是这个问题:stackoverflow.com/questions/25596881/…

标签: html ruby regex


【解决方案1】:

你可以使用这个正则表达式:

.*?iframe src=".*?(?:youtube|soundcloud|vimeo).*?".*|(.*?iframe src=".*?".*)

Working demo

您可以看到,对于第一个输入(绿色输入),输出就是您在问题中指定的内容。蓝色匹配没有输出,因为它是 youtube、soundcloud 或 vimeo 的有效匹配。

比赛信息

MATCH 1
1.  [0-155] `<p><iframe src="http://www.3you3tube.com/embed/YoX1yc92MOU" width="500" height="300" frameborder="0" scrolling="auto"></iframe></p>`

【讨论】:

    【解决方案2】:
    <iframe.*?src="(?![^"]*(?:youtube|vimeo|soundcloud)).*?<\/iframe>
    

    Demo


    这里的关键是iframe.*?src="(?=[^"]*(?:youtube|vimeo|soundcloud)),所以让我为你扩展一下:

    iframe                          ?# literally match iframe
    .*?                             ?# lazily match 0+ characters
    src="                           ?# literally match src="
    (?!                             ?# start negative lookahead assertion
      [^"]*                         ?# match 0+ non-" characters
      (?:youtube|vimeo|soundcloud)  ?# match one of the domains
    )                               ?# end assertion
    

    因此,一旦表达式到达iframesrc 属性,它将在任意数量的非" 字符之后为其中一个域否定断言(换句话说,直到src 属性)。只要我们在属性中找不到这些域之一,我们就会继续懒惰地匹配 iframe 的其余部分(直到结束标记)。

    【讨论】:

    • @QambarRaza thisthis..?
    • 这正是我想要的!
    • 只是为了让您知道解决方案是:/<iframe.*?src="(?![^"]*(?:youtube|vimeo|soundcloud)).*?< \\iframe>/m
    【解决方案3】:

    众所周知,使用正则表达式解析 HTML 很困难除非您拥有该 HTML 的生成,即使这样也很痛苦。

    相反,除了最微不足道的用途之外,请使用解析器,它可以规范化许多导致模式失败的问题。

    提交的模式将失败,因为它们假定 src 参数的标记名大小写、空格和字符串分隔符。这些可以容纳在模式中,但不打扰更容易。在以下代码中,所有被检查的字符串都是有效的 HTML:

    require 'htmlentities'
    require 'nokogiri'
    
    [
      %#&lt;p&gt;&lt;iframe\nsrc="http://www.youtube.com/embed/YoX1yc92MOU_1"&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;iframe\nsrc= "http://www.youtube.com/embed/YoX1yc92MOU_2"&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;iframe\nsrc = "http://www.youtube.com/embed/YoX1yc92MOU_3"&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;iframe\nsrc = 'http://www.youtube.com/embed/YoX1yc92MOU_4'&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;Iframe\nsrc = 'http://www.youtube.com/embed/YoX1yc92MOU_5'&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;IFRAME\nsrc = 'http://www.youtube.com/embed/YoX1yc92MOU_6'&lt;/iframe&gt;&lt;/p&gt;#,
      %#&lt;p&gt;&lt;IFRAME\nsrc =
      'http://www.youtube.com/embed/YoX1yc92MOU_7'&lt;/iframe&gt;&lt;/p&gt;#,
    ].each do |text|
      html = HTMLEntities::Decoder.new('html4').decode(text)
      doc = Nokogiri::HTML::DocumentFragment.parse(html)
    
      iframe = doc.at('iframe')
      puts "Ignoring: #{ iframe['src'] }" if iframe['src'][/\b(?:youtube|soundcloud|vimeo)\b/i]
    end
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_1
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_2
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_3
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_4
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_5
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_6
    # >> Ignoring: http://www.youtube.com/embed/YoX1yc92MOU_7
    

    RegEx match open tags except XHTML self-contained tags”是 Stack Overflow 上出现此类问题时的必填链接。最著名的答案当然是半开玩笑,但重点是不要用模式来做这件事。

    在上面的代码中,/\b(?:youtube|soundcloud|vimeo)\b/i 是一个正则表达式,但它又短又甜,根本不适用于 HTML。相反,它用于 src 参数的内容,该参数在(编码的)HTML 中必须是正确的,并且不能被破坏/修改,否则 iframe 本身将无法工作。

    【讨论】:

      猜你喜欢
      • 2017-05-24
      • 2023-04-08
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 2015-07-05
      • 2011-06-11
      • 1970-01-01
      • 2015-05-29
      相关资源
      最近更新 更多