【问题标题】:What is the regular expression to get a token of a URL?获取 URL 令牌的正则表达式是什么?
【发布时间】:2010-08-15 20:31:10
【问题描述】:

【问题讨论】:

  • 不要使用正则表达式解析 HTML。你在哪个平台?可以有多个子目录吗?
  • 从字符串结尾回溯:/([^\/]+)\..+$/
  • 正则表达式将在 javascript 中运行?
  • 我正在使用 C++ 和 boost::regex

标签: c++ regex boost


【解决方案1】:

RFC 2396 的附录 B 提供了一些用于将 URI 拆分为其组件的正则表达式,我们可以根据您的情况对其进行调整

^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*/([^.]+)[^?#]*)(\?([^#]*))?(#(.*))?
                                     #######

这会将The_Token_I_Want 留在$6 中,这是上面的“hashderlined”子表达式。 (请注意,哈希不是模式的一部分。)现场观看:

#! /usr/bin/perl

$_ = "http://domain.com/133742/The_Token_I_Want.zip";    
if (m!^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*/([^.]+)[^?#]*)(\?([^#]*))?(#(.*))?!) {
  print "$6\n";
}
else {
  print "no match\n";
}

输出:

$ ./prog.pl
The_Token_I_Want

更新:我在评论中看到您正在使用boost::regex,因此请记住在您的 C++ 程序中转义反斜杠。

#include <boost/foreach.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <string>

int main()
{
  boost::regex token("^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*"
                     "/([^.]+)"
                   //  ####### I CAN HAZ HASHDERLINE PLZ
                     "[^?#]*)(\\?([^#]*))?(#(.*))?");

  const char * const urls[] = {
    "http://domain.com/133742/The_Token_I_Want.zip",
    "http://domain.com/12345/another_token.zip",
    "http://domain.com/0981723/YET_ANOTHER_TOKEN.zip",
  };

  BOOST_FOREACH(const char *url, urls) {
    std::cout << url << ":\n";

    std::string t;
    boost::cmatch m;
    if (boost::regex_match(url, m, token))
      t = m[6];
    else
      t = "<no match>";

    std::cout << "  - " << m[6] << '\n';
  }

  return 0;
}

输出:

http://domain.com/133742/The_Token_I_Want.zip:
  - The_Token_I_Want
http://domain.com/12345/another_token.zip:
  - 另一个令牌
http://domain.com/0981723/YET_ANOTHER_TOKEN.zip:
  - YET_ANOTHER_TOKEN

【讨论】:

  • 只获得一个组件会不会有点过头了?
  • 矫枉过正与否,我投票赞成将“hashderlined”添加到字典中。
【解决方案2】:
/a href="http://domain.com/[0-9]+/([a-zA-Z_]+).zip"/

可能想在 [a-zA-Z_]+ 中添加更多字符

【讨论】:

    【解决方案3】:

    你可以使用:

    (http|ftp)+://[[:alnum:]./_]+/([[:alnum:]._-]+).[[:alnum:]_-]+
    

    ([[:alnum:]._-]+) 是匹配模式的组,在您的示例中,其值为The_Token_I_Want。要访问该组,请使用 \2 或 $2,因为 (http|ftp) 是第一个组,而 ([[:alnum:]._-]+ ) 是匹配模式的第二组。

    【讨论】:

      【解决方案4】:

      试试这个:

      /(?:f|ht)tps?:/{2}(?:www.)?domain[^/]+.([^/]+).([^/]+)/i

      /\w{3,5}:/{2}(?:w{3}.)?domain[^/]+.([^/]+).([^/]+)/i

      【讨论】:

        【解决方案5】:

        首先,使用 HTML 解析器并获取 DOM。然后获取锚元素并遍历它们以查找 href。不要试图直接从字符串中获取令牌。

        然后:

        油嘴滑舌的答案是:

        /(The_Token_I_Want.zip)/
        

        您可能希望比单个示例更精确一些。

        我猜你实际上在寻找:

        /([^/]+)$/
        

        【讨论】:

          【解决方案6】:
          m/The_Token_I_Want/
          

          您必须更具体地了解它是什么类型的令牌。一个号码?一个字符串?它会重复吗?它有形式或模式吗?

          【讨论】:

            【解决方案7】:

            最好使用比 RegEx 更智能的东西。例如,如果您使用 C#,则可以使用 System.Uri 类为您解析它。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2011-01-20
              • 2012-10-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-06-13
              • 1970-01-01
              • 2011-06-15
              相关资源
              最近更新 更多