如何从字符串中提取包含非英语字符的URL?

这是一个简单的脚本,它带有一个带有德语URL的锚标记,并提取URL:

# encoding: utf-8 require 'uri' url = URI.extract('München') puts url 

 http://www.example.com/wp-content/uploads/2012/01/M 

extract方法在ü处停止。 如何才能使用非英文字母? 我正在使用ruby-1.9.3-p0。

Ruby的内置URI对某些东西很有用,但在处理国际字符或IDNA地址时它不是最佳选择。 为此,我建议使用Addressable gem。

这是一些清理过的IRB输出:

 require 'addressable/uri' url = 'http://www.example.com/wp content/uploads/2012/01/München.jpg' uri = Addressable::URI.parse(url) 

这就是Ruby现在所知道的:

 # 

看路径,你可以看到它,或者它应该是:

 1.9.2-p290 :004 > uri.path # => "/wp content/uploads/2012/01/München.jpg" 1.9.2-p290 :005 > uri.normalized_path # => "/wp%20content/uploads/2012/01/M%C3%BCnchen.jpg" 

考虑到互联网如何转向更复杂的URI和混合的Unicode字符,应该选择Addressable来替换Ruby的URI。

现在,获取字符串也很容易,但取决于您需要查看多少文本。

如果您有完整的HTML文档,最好的办法是使用Nokogiri解析HTML并从标签中提取href参数。 这是从单个开始的地方:

 require 'nokogiri' html = 'München' doc = Nokogiri::HTML::DocumentFragment.parse(html) doc.at('a')['href'] # => "http://www.example.com/wp content/uploads/2012/01/München.jpg" 

使用DocumentFragment解析可以避免将片段包装在通常的标记中。 对于您想要使用的完整文档:

 doc = Nokogiri::HTML.parse(html) 

这是两者之间的区别:

 irb(main):006:0> Nokogiri::HTML::DocumentFragment.parse(html).to_html => "München" 

与:

 irb(main):007:0> Nokogiri::HTML.parse(html).to_html => "\nMünchen\n" 

因此,使用第二个用于完整的HTML文档,对于一个小的部分块,使用第一个。

要扫描整个文档,提取所有href,请使用:

 hrefs = doc.search('a').map{ |a| a['href'] } 

如果你只有你在示例中显示的小字符串,你可以考虑使用一个简单的正则表达式来隔离所需的href

 html[/href="([^"]+)"/, 1] => "http://www.example.com/wp content/uploads/2012/01/München.jpg" 

您必须先对URL进行编码:

 URI.extract(URI.encode('München')) 

URI模块可能仅限于7位ASCII字符。 虽然UTF-8是很多东西的假定标准,但这绝不可靠,并且没有办法像完成HTTP交换一样指定URI的编码。

一种解决方案是将非ASCII字符呈现为它们的%等价物。 相关堆栈溢出post: URL中的Unicode字符

如果您正在处理已经损坏的数据,您可能需要首先调用URI.encodeURI.encode它,然后再次匹配它。