0

在我的一个项目中,应用程序必须检查给定页面中是否存在指向给定 URL 的链接。今天有用户报错。这是应用程序未检测到的链接:

  <a\nhref="http://hello.com"...

我试图测试它为什么不起作用,这就是奇怪行为出现的地方。此正则表达式与链接匹配:

/\<a.*\nhref=\"http:\/\/hello.com/

但这不会:

/\<a.*href=\"http:\/\/hello.com/

我猜它与我正在使用的 Ruby 版本(1.9.3)有一些关系,因为 Rubular 匹配最后一个正则表达式。

4

2 回答 2

4

为什么它坏了

在 Ruby 中(与大多数正则表达式实现一样).匹配除换行符以外的任何字符,除非您打开“多行”模式:

irb(main):003:0> "foo\nbar"[/.+/]
#=> "foo"

irb(main):004:0> "foo\nbar"[/.+/m]
#=> "foo\nbar"

正如官方 Ruby 1.9 正则表达式文档所述:

以下元字符的行为也类似于字符类:
/./- 除换行符以外的任何字符。
/./m- 任何字符(m 修饰符启用多行模式)

当您的代码显式使用\nall 时效果很好,但是当您将其切换到 just 时,.*它无法匹配\n,因此无法继续匹配href

更好地修复它

与其使用正则表达式来解析和使用 HTML,不如使用真正的 HTML 解析器

require 'nokogiri' # gem install nokogiri
doc = Nokogiri.HTML( my_html_string )

# Find it using XPath...
first_hello_link = doc.at('//a[starts-with(@href,"http://hello.com")]')

# ...or using CSS
first_hello_link = doc.at('a[href^="http://hello.com"]')

有了这个,您的代码可以通过以下方式稳健地处理 HTML:

  • 等号之前或之后的空格
  • 出现在 href 之前的附加属性
  • 引用"或者'
  • 混合大小写
  • 看起来像链接但不是的东西(例如在评论或脚本块中)
于 2012-05-07T15:41:40.427 回答
1

ruby 中的正则表达式默认不匹配换行符,您必须添加m修饰符:

/pat/m - Treat a newline as a character matched by .

看看选项部分:

http://www.ruby-doc.org/core-1.9.3/Regexp.html

于 2012-05-07T15:43:24.793 回答