如题,想请问,假设
A="http://www.msn.com\nhttp://www.yahoo.com\nhttp://www.abc.com\n"
B="http://www.msn.com\nhttp://www.yahoo.com\n"
如果我要在A的网址中找出差异,希望传回 http://www.abc.com\n
该如何做呢?
我试了很久,都试不出来.
[b]问题补充:[/b]
可以在请教一下 :oops:
如果像这样的状况 :
a="Link</>456"
b="href="
想抽出所有在a中,href=之后的连结,也可以用这方法吗?
PS:a内容会变动.
碰到HTML还不如用Nokogiri来解析一下。自己写正则表达式很容易写错而且又不容易发现错误。如果你要解析的文档里里有href以外的属性,例如说target、type、title之类,那用正则表达式解析起来就不怎么方便。
没装Nokogiri的话用gem install nokogiri来安装就行。在Ruby 1.9.1-p0上现在貌似还有点问题,不过在1.8.6上很正常。
[code="ruby"]require 'nokogiri'
html = "Link456"
doc = Nokogiri::HTML.parse html
(doc/'a').map {|n| n['href'] }
#=> ["123.htm", "456.htm"][/code]
非要自己用正则表达式的话……嗯,这样?
[code="ruby"]html = "Link456"
html.scan(//).map {|m| m[1] }
#=> ["123.htm", "456.htm"][/code]
如果“差异”是以B的内容必须完整连续的在A中出现为前提的话,那用/^(.*?)(?:#{b})(.*)$/m,很方便。注意要用m(multiline,多行匹配模式),不然.不会匹配换行符。
看看这段irb session,像这样就可以了:
[code="ruby"]irb(main):001:0> a = "http://www.msn.com\nhttp://www.yahoo.com\nhttp://www.abc.com\n"
=> "http://www.msn.com\nhttp://www.yahoo.com\nhttp://www.abc.com\n"
irb(main):002:0> b = "http://www.msn.com\nhttp://www.yahoo.com\n"
=> "http://www.msn.com\nhttp://www.yahoo.com\n"
irb(main):003:0> r = /^(.*?)(?:#{b})(.*)$/m
=> /^(.*?)(?:http:\/\/www.msn.com
http:\/\/www.yahoo.com
)(.*)$/m
irb(main):004:0> a =~ r
=> 0
irb(main):005:0> "#$1#$2"
=> "http://www.abc.com\n"[/code]
不过如果B中出现的内容在A里不一定是完整连续的话,这个正则表达式就用不了了,请注意。
呃,手快习惯性的写了(?:...),不用这个非捕获型分组括号也可以,直接把b的内容放到正则表达式里:
[code="ruby"]/^(.*?)#{b}(.*)$/m[/code]
其实很简单,只需要把换行替换成'|'(或),然后把a中与b匹配的部分删除掉就行了
[code="ruby"]
re = Regexp.new(Regexp.escape(b).gsub '\n', '\n|') #注意是单引号
result = a.gsub re, ''
[/code]
hmm, 那即使不替换掉换行符号,直接用m模式来gsub也行:
[code="ruby"]a = "http://www.msn.com\nhttp://www.yahoo.com\nhttp://www.abc.com\n"
b = "http://www.msn.com\nhttp://www.yahoo.com\n"
r = /#{b}/m
result = a.gsub r, ''
#=> "http://www.abc.com\n"[/code]
呵呵,就是。这么简单
我也又学习了一遍 T T
gsub那么好用我却总是想着匹配整字符串再拿出捕获分组。摇头。以前有段时间明明已经改掉这个坏习惯了的……
用String#scan
[code="ruby"]
b = 'href='
a.scan /#{b}\s*'"['"]/
[/code]
当然更准确一点的是从语义上解析,用rexml
参考The Ruby Way第15章,用SAX-like parsing就足够了
赞啦,标记一下,学习