2012-10-28 23 views
0

拿这个代码片断这应该与它的URL替换href标记:Ruby 1.9.3正则表达式与gsub:错误或功能?

irb> s='<p><a href="http://localhost/activate/57f7e805827f" style="color:#F19300;font-weight:bold">Click here!</a></p>' 
irb> s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^<]*)<\/a>/, "#{$1}") 
=> "<p></p>" 

此正则表达式失败(网址未找到)。然后,我逃避了正则表达式的<性格,它的工作原理:

irb> s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^\<]*)<\/a>/, "#{$1}") 
=> "<p>http://localhost/activate/57f7e805827f</p>" 

1:根据的RubyMine的检查,这种逃避不应该是必要的。它是否正确?如果是这样,为什么>的逃跑显然不需要?

2:然后在同一会话IRB,用相同的字符串,原正则表达式突然也工作:

irb> s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^<]*)<\/a>/, "#{$1}") 
=> "<p>http://localhost/activate/57f7e805827f</p>" 

这是因为再次调用gsub$1变量没有被清除?如果是这样,这是故意的行为还是这是一个Ruby正则表达式错误?

3:当我改变字符串,并重新执行相同的命令,$1只会调用gsub后更改两次变更后的字符串:

irb> s='<p><a href="http://localhost/activate/xxxxyyy" style="color:#F19300;font-weight:bold">Click here!</a></p>' 
=> "<p><a href=\"http://localhost/activate/xxxxyyy\" style=\"color:#F19300;font-weight:bold\">Click here!</a></p>" 
irb> s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^\<]*)<\/a>/, "#{$1}") 
=> "<p>http://localhost/activate/57f7e805827f</p>" 
irb> s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^\<]*)<\/a>/, "#{$1}") 
=> "<p>http://localhost/activate/xxxxyyy</p>" 

这是故意的吗?如果是这样,这背后的逻辑是什么?

4:作为替换字符,有些教程建议使用"#{$n}",其他建议使用'\n'。使用反斜杠变体时,上述问题不会出现。为什么 - 两者有什么区别?

谢谢!

回答

2

$1包含了最后一场比赛的第一个捕获。在你的例子中,在之前评估(实际上甚至在调用gsub之前),因此$1的值固定为nil(因为你还没有匹配任何东西)。所以,你总能得到以前场比赛的第一次捕捉,你甚至都不需要改变你原来的正则表达式来获得期望的结果,第二次:

s='<p><a href="http://localhost/activate/57f7e805827f" style="color:#F19300;font-weight:bold">Click here!</a></p>' 

s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^<]*)<\/a>/, "#{$1}") 
# => "<p></p>" 

s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^<]*)<\/a>/, "#{$1}") 
# => "<p>http://localhost/activate/57f7e805827f</p>" 

你可以传递一个块gsub,虽然,这匹配,电子后评价。 G。

s.gsub(/<a href="([^ '"]*)"([^>]*)?>([^<]*)<\/a>/){ $1 } 
# => "<p>http://localhost/activate/57f7e805827f</p>" 

这样,$1的行为与您所期望的相同。我喜欢总是使用命名捕捉,所以当我添加捕捉时我不必跟踪数字,但是:

s.gsub(/<a href="(?<href>([^ '"]*))"([^>]*)?>([^<]*)<\/a>/){ $~[:href] } 
# => "<p>http://localhost/activate/57f7e805827f</p>" 
+0

谢谢,这使得总体感。 – Jens