1

我在以下文本中有 html 内容。

    "This is my text to be parsed which contains url 
    http://someurl.com?param1=foo&params2=bar 
 <a href="http://thisshouldnotbetampered.com">
    some text and a url http://someotherurl.com test 1q2w
 </a> <img src="http://someasseturl.com/abc.jpeg"/>
    <span>i have a link too http://someurlinsidespan.com?xyz=abc </span> 
    "

需要一个将普通网址转换为超链接的正则表达式(不篡改现有的超链接)

预期结果:

    "This is my text to be parsed which contains url 
    <a href="http://someurl.com?param1=foo&params2=bar">
http://someurl.com?param1=foo&params2=bar</a> 
 <a href="http://thisshouldnotbetampered.com">
    some text and a url http://someotherurl.com test 
1q2w </a> <img src="http://someasseturl.com/abc.jpeg"/>
    <span>i have a link too <a href="http://someurlinsidespan.com?xyz=abc">http://someurlinsidespan.com?xyz=abc</a> </span> "
4

4 回答 4

3

免责声明:您不应为此任务使用正则表达式,而应使用 html 解析器。这是一个POC,用于证明如果您期望格式良好的 HTML(无论如何您都不会拥有),这是可能的。

所以这就是我想出的:
(https?:\/\/(?:w{1,3}.)?[^\s]*?(?:\.[a-z]+)+)(?![^<]*?(?:<\/\w+>|\/?>))

这是什么意思 ?

  • (: 第一组
  • https?: 匹配httphttps
  • \/\/: 匹配//
  • (?:w{1,3}.)?: 可选匹配w.ww.www.
  • [^\s]*?: 匹配除空格以外的任何内容零次或多次不贪婪
  • (?:\.[a-z]+)+): 匹配一个点后跟一个[a-z]字符,重复一次或多次
  • (?!: 负前瞻
    • [^<]*?: 匹配除<零次或多次不贪婪之外的任何内容
    • (?:<\/\w+>|\/?>): 匹配结束标签或/>>
    • ): 前瞻结束
  • ): 第 1 组结束


                           regex101 online demo                                            rubular online demo

于 2013-06-11T08:20:18.500 回答
2

也许您可以先进行搜索和替换以删除 HTML 元素。我不了解 Ruby,但正则表达式类似于/<(\w+).*?>.*?</\1>/. 但是如果你有相同类型的嵌套元素,这可能会很棘手。

于 2013-06-11T07:50:54.027 回答
0

也许尝试http://rubular.com/ .. 有一些Regex提示可以帮助您获得所需的输出。

于 2013-06-11T08:23:23.813 回答
0

我会做这样的事情:

require 'nokogiri'

doc = Nokogiri::HTML.fragment <<EOF
This is my text to be parsed which contains url 
http://someurl.com  <a href="http://thisshouldnotbetampered.com">
some text and a url http://someotherurl.com test 1q2w </a> <img src="http://someasseturl.com/abc.jpeg"/>
EOF

doc.search('*').each{|n| n.replace "\n"}

URI.extract doc.text
#=> ["http://someurl.com"]
于 2013-06-11T09:43:36.453 回答