【问题标题】:How can I match a URL but exclude terminators from the match?如何匹配 URL 但从匹配项中排除终止符?
【发布时间】:2011-03-27 18:07:31
【问题描述】:

我想匹配文本中的 url 并用锚标记替换它们,但我想排除一些终止符,就像 Twitter 如何匹配推文中的 url。

到目前为止,我已经掌握了这个,但显然效果不太好。

(http[s]?\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?)

编辑:一些示例网址。在以下所有情况下,我只想匹配“http://www.example.com”

http://www.example.com.

http://www.example.com:

“http://www.example.com”

http://www.example.com;

http://www.example.com!

[http://www.example.com]

{http://www.example.com}

http://www.example.com*

【问题讨论】:

  • 您能否详细说明您的示例?我看到右括号和大括号,但没有开口。另外大括号和括号有什么区别?
  • 我不确定` has a special meaning inside [ ]`(至少在 perl/python 中没有,我不知道 ruby​​)。你能发布你的正则表达式 确实 匹配的部分吗?
  • 使用URI,而不是正则表达式。

标签: ruby regex


【解决方案1】:

我去年研究了这个问题并开发了一个您可能想要查看的解决方案 - 请参阅:URL Linkification (HTTP/FTP) 此链接是 Javascript 解决方案的测试页面,其中包含许多难以链接的 URL 示例。

我为 PHP 和 Javascript 编写的正则表达式解决方案(但可以很容易地转换为 Ruby)并不简单(但事实证明也不是问题。)有关更多信息,我建议您阅读:

The Problem With URLs 来自 Jeff Atwood,
An Improved Liberal, Accurate Regex Pattern for Matching URLs 来自 John Gruber

如果您想正确执行此操作,则必须阅读 Jeff 博客文章后的 cmets...

【讨论】:

    【解决方案2】:

    Ruby 的 URI 模块有一个 extract 方法,用于从文本中解析出 URL。通过解析返回的值,您可以利用模块中的启发式方法从 URL 中提取方案和主机信息,避免重新发明轮子。

    text = '
    http://www.example.com.
    http://www.example.com:
    "http://www.example.com"
    http://www.example.com;
    http://www.example.com!
    [http://www.example.com]
    {http://www.example.com}
    http://www.example.com*
    http://www.example.com/foo/bar?q=foobar
    http://www.example.com:81
    '
    
    require 'uri'
    
    puts URI::extract(text).map{ |u| uri = URI.parse(u); "#{ uri.scheme }://#{ uri.host[/(^.+?)\.?$/, 1] }" }
    
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    # >> http://www.example.com
    

    唯一的问题是句点 '.' 是主机名中的合法字符,因此 URI#host 不会删除它。那些在重新构建 URL 的 map 语句中被捕获。请注意,URI 正在剥离路径和查询信息。

    【讨论】:

      【解决方案3】:

      一个实用且易于理解的解决方案是:

      regex = %r!"(https?://[-.\w]+\.\w{2,6})"!
      

      一些注意事项:

      • 使用 %r 我们可以选择开始和结束分隔符。在这种情况下,我使用了感叹号,因为我想在正则表达式中使用未转义的斜杠。
      • 可选的量词(即“?”)仅绑定到前面的表达式,在本例中为“s”。无需将“s”放在字符类[s]? 中。和s?一样。
      • 在字符类[-.\w] 中,我们不需要转义破折号和点来使它们与点和破折号字面意思匹配。但是,破折号应该排在第一位,而不是表示范围。
      • \w 匹配 Ruby 中的 [A-Za-z0-9_]。这并不是 URL 字符的完整定义,但结合破折号和点可能足以满足我们的需求。
      • 顶级域的长度在 2 到 6 个字符之间,例如'.se' 和 '.travel'
      • 我不确定您所说的 我想排除一些终止符是什么意思,但是这个正则表达式只匹配您示例中想要的那个。
      • 我们想使用第一个捕获组,例如像这样:

        如果输入 =~ %r!"(https?://[-.\w]+.\w{2,6})"!

        匹配 = $~[1]

        其他

        匹配 = ""

        结束

      【讨论】:

        【解决方案4】:

        这个呢?

        %r|https?://[-\w.]*\w|
        

        【讨论】:

          猜你喜欢
          • 2019-03-25
          • 1970-01-01
          • 1970-01-01
          • 2012-10-17
          • 1970-01-01
          • 2014-05-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多