【问题标题】:CPP + Regular Expression to Validate URLCPP + 正则表达式来验证 URL
【发布时间】:2011-08-02 23:26:46
【问题描述】:

我想在 c++{MFC} 中构建一个验证 URL 的正则表达式。

正则表达式必须满足以下条件。

有效网址:- http://cu-241.dell-tech.co.in/MyWebSite/ISAPIWEBSITE/Denypage.aspx/ http://www.google.com http://www.google.co.in

无效的网址:-

  1. http://cu-241.dell-tech.co.in/\MyWebSite/\ISAPIWEBSITE/\Denypage.aspx/ = Regx 必须检查“/\MyWebSite/\ISAPIWEBSITE/\Denypage.aspx/”之间的无效 URL 作为 '\' 字符

  2. http://cu-241.dell-tech.co.in//////MyWebSite/ISAPIWEBSITE/Denypage.aspx/ = 由于 url 中有多个“//////”条目,Regx 必须检查并使 URL 无效。

  3. http://news.google.co.in/%5Cnwshp?hl=en&tab=wn = 正则表达式必须检查 URL 并使 URL 无效才能额外插入 %5C 和 %2F 字符。

我们如何开发一个满足上述条件的通用正则表达式。 请提供一个正则表达式来帮助我们处理 CPP{MFC} 中的上述场景

【问题讨论】:

    标签: c++ c regex mfc visual-c++


    【解决方案1】:

    您是否尝试过使用RFC 3986 建议?如果您能够使用 GCC-4.9,那么您可以直接使用 <regex>

    它指出使用^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?,您可以获得子匹配项:

      scheme    = $2
      authority = $4
      path      = $5
      query     = $7
      fragment  = $9
    

    例如:

    int main(int argc, char *argv[])
    {
      std::string url (argv[1]);
      unsigned counter = 0;
    
      std::regex url_regex (
        R"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)",
        std::regex::extended
      );
      std::smatch url_match_result;
    
      std::cout << "Checking: " << url << std::endl;
    
      if (std::regex_match(url, url_match_result, url_regex)) {
        for (const auto& res : url_match_result) {
          std::cout << counter++ << ": " << res << std::endl;
        }
      } else {
        std::cerr << "Malformed url." << std::endl;
      }
    
      return EXIT_SUCCESS;
    }
    

    然后:

    ./url-matcher http://localhost.com/path\?hue\=br\#cool
    
    Checking: http://localhost.com/path?hue=br#cool
    0: http://localhost.com/path?hue=br#cool
    1: http:
    2: http
    3: //localhost.com
    4: localhost.com
    5: /path
    6: ?hue=br
    7: hue=br
    8: #cool
    9: cool
    

    【讨论】:

    • 这真的很棒。你能告诉我如何使用它来使用正则表达式提取字符串中的所有匹配网址吗?我尝试将它与 sregex_iterator 一起使用,但我没有得到任何匹配。非常感谢!
    • 不幸的是,这不是用于验证,而是用于将正确的 URI 拆分为各个部分。它甚至不会检测到最简单的情况,例如未编码的空格。
    • 感谢您提供如此有用且解释清楚的答案。这是我发现的最好的全方位 URL 解析脚本,它具有准确性、易用性和实施​​速度。而且您不需要下载任何特殊的库!它会很好地回答这个问题:*.com/q/2616011/1043704
    • 请注意,如果存在端口,它将包含在元素 3 和 4 中。即,http://localhost.com:8888/path?hue=br#cool 导致 3: //localhost.com:88884: localhost.com:8888
    • 不工作,"aaa" 将被这个表达式接受
    【解决方案2】:

    查看http://gskinner.com/RegExr/,右侧有一个社区选项卡,您可以在其中找到贡献的正则表达式。有一个 URI 类别,不确定您是否能准确找到所需的内容,但这是一个好的开始

    【讨论】: