使用Ruby regex将内容放在字符串的中间

时间:2013-01-21 04:58:51

标签: ruby regex

我有一个这样的字符串:

  

SRC =“http://www.google.com/calendar/embed?showTitle=0&mode=WEEK&height=600&wkst=1&bgcolor=%23FFFFFF&src=59flluvbaj110hp6ht5hrveof8%40group。 calendar.google.com & color =%23B1365F& src = cnuvtn9nofljk5kq9381ic5odg%40group.calendar.google.com& color =%232952A3& ctz = America%2FNew_York“style =”border-width:0“width = “800”height =“600”frameborder =“0”scrolling =“no”

我想以粗体提取该部分。它始终位于src=&之间。目前,我正在做

"sample string above".match(/;src.*?&/)[0][5, length-5]

但这似乎非常不优雅。有更好的方法吗?

4 个答案:

答案 0 :(得分:2)

"sample string above"[/&src=(.*?)&/, 1]

1表示第一个捕获组

答案 1 :(得分:1)

你根本不需要正则表达式,只需了解发生的事情。问题是src的内容已针对HTML实体进行编码,因此,将变量之间的嵌入&编码为&

修复方法是首先解码字符串以反转编码,然后将字符串拆分回其组件。您可以使用以下方式执行此操作:

require 'cgi'
require 'uri'

uri = URI.parse(src)
hash = Hash[URI::decode_www_form(CGI::unescapeHTML(uri.query))]
hash['src'] # => "cnuvtn9nofljk5kq9381ic5odg@group.calendar.google.com"

将查询解码为哈希的替代方法是:

hash = Hash[CGI::unescapeHTML(uri.query).split('&').map{ |q| q.split('=') }]

通过拆分&,然后=我们得到一个数组数组,并且可以轻松地将其转换回Hash,从而可以轻松访问字符串中的任何变量。

虽然这些似乎是一条较长的路径,但它们可以解决问题并将值恢复为原始形式。

通常我们希望它作为哈希,但在这种情况下我们不能做到这一切,因为它们在查询中有两个"src"参数,导致第二个踩踏第一个。如果你想要第一个而不是第二个,你需要抓住它而不转换为哈希:

URI::decode_www_form(CGI::unescapeHTML(uri.query)).select{ |k,v| k == 'src' }
=> [["src", "*59flluvbaj110hp6ht5hrveof8@group.calendar.google.com*"], ["src", "cnuvtn9nofljk5kq9381ic5odg@group.calendar.google.com"]]

URI::decode_www_form(CGI::unescapeHTML(uri.query)).select{ |k,v| k == 'src' }[0]
=> ["src", "*59flluvbaj110hp6ht5hrveof8@group.calendar.google.com*"]

URI::decode_www_form(CGI::unescapeHTML(uri.query)).select{ |k,v| k == 'src' }[1]
=> ["src", "cnuvtn9nofljk5kq9381ic5odg@group.calendar.google.com"]

您显示的字符串看起来不正确,而是看起来像您从HTML剪切和粘贴的内容。如果是这样,您应该使用解析器来提取内容,而不是正则表达式。而且,在这种情况下,这是如何正确地做到这一点:

require 'nokogiri'

html = '<img src="http://www.google.com/calendar/embed?showTitle=0&mode=WEEK&height=600&wkst=1&bgcolor=%23FFFFFF&src=59flluvbaj110hp6ht5hrveof8%40group.calendar.google.com&color=%23B1365F&src=cnuvtn9nofljk5kq9381ic5odg%40group.calendar.google.com&color=%232952A3&ctz=America%2FNew_York" style=" border-width:0 " width="800" height="600" frameborder="0" scrolling="no">'

doc = Nokogiri.HTML(html)
src = doc.at('img')['src']
=> "http://www.google.com/calendar/embed?showTitle=0&mode=WEEK&height=600&wkst=1&bgcolor=%23FFFFFF&src=59flluvbaj110hp6ht5hrveof8%40group.calendar.google.com&color=%23B1365F&src=cnuvtn9nofljk5kq9381ic5odg%40group.calendar.google.com&color=%232952A3&ctz=America%2FNew_York"

Nokogiri at method doc.at('img')可能会因文档中<img>标记的位置而发生变化,但处理该问题则是一个单独的问题。

答案 2 :(得分:0)

您可以使用捕获组执行此操作,如下所示:

"sample string above".sub(/^.*src=(.*?)&.*$/, '\1')

答案 3 :(得分:0)

修复报价分隔符

您最初发布的字符串有引用问题。确保你正确地逃脱了你的字符串。例如,您可以使用以下替代语法:

  

src =%q {http://www.google.com/calendar/embed?showTitle=0&mode=WEEK&height=600&wkst=1&bgcolor=%23FFFFFF&src=59flluvbaj110hp6ht5hrveof8%40group.calendar .google.com&amp; color =%23B1365F&amp; src = cnuvtn9nofljk5kq9381ic5odg%40group.calendar.google.com&amp; color =%232952A3&amp; ctz = America%2FNew_York“style =”border-width:0“width =”800“height =” 600“frameborder =”0“scrolling =”no“}

使用正面观察

您可以使用正向lookbehind断言扫描字符串以查找所有匹配项,然后使用适当的Array方法访问您感兴趣的字符串。例如:

src.scan(/(?<=src=)[^&]+/).first
# => "59flluvbaj110hp6ht5hrveof8%40group.calendar.google.com"