在我的一个项目中,应用程序必须检查给定页面中是否存在指向给定URL的链接。今天用户报告了一个错误。这是应用程序未检测到的链接:
<a\nhref="http://hello.com"...
我试着测试它为什么不起作用,这里出现了奇怪的行为。此正则表达式匹配链接:
/\<a.*\nhref=\"http:\/\/hello.com/
但这不是:
/\<a.*href=\"http:\/\/hello.com/
我猜它与我正在使用的Ruby版本有一些关系(1.9.3),因为Rubular匹配最后一个正则表达式。
答案 0 :(得分:4)
在Ruby中(与大多数正则表达式实现一样).
匹配除换行符之外的任何字符 ,除非您打开“多行”模式:
irb(main):003:0> "foo\nbar"[/.+/]
#=> "foo"
irb(main):004:0> "foo\nbar"[/.+/m]
#=> "foo\nbar"
正如official Ruby 1.9 regex documentation所述:
以下元字符的行为也类似于字符类:
/./
- 除换行符之外的任何字符/./m
- 任何字符(m修饰符启用多行模式)
当您明确使用\n
的代码时效果很好,但当您将其切换为.*
时,它与\n
无法匹配,因此无法继续匹配href
1}}。
不使用正则表达式来解析和使用HTML,最好使用a real HTML parser:
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:
"
或'
答案 1 :(得分:1)
默认情况下,ruby中的正则表达式与换行符不匹配,您必须添加m
修饰符:
/pat/m - Treat a newline as a character matched by .
查看选项部分: