【问题标题】:Regex for a URL Connection StringURL 连接字符串的正则表达式
【发布时间】:2017-12-17 19:19:00
【问题描述】:

是否有已知的 JavaScript 正则表达式来匹配整个 URL 连接字符串?

protocol://user:password@hostname:12345/segment1/segment2?p1=val1&p2=val2

我正在寻找一个可以帮助我将这样的连接字符串转换为对象的正则表达式:

{
    protocol: 'protocol',
    user: 'user',
    password: 'password',
    host: 'hostname:12345',
    hostname: 'hostname',
    port: 12345,
    segments: ['segment1', 'segment2'],
    params: {
        p1: 'val1',
        p2: 'val2'
    }
}

另外,我希望连接字符串的每一部分都是可选的,因此缺少的参数可以由环境中的值填充。

示例:

  • protocol://
  • server:12345
  • :12345 - 仅适用于端口
  • user:password@
  • user@
  • :password@
  • /segment1
  • ?p1=val1
  • 等等……

当涉及到有效符号时,标准RFC 3986 规则应适用于所有部分。

我正在寻找适用于 Node.js 和所有浏览器的东西。

我已经在 connection-string 中进行了一个单独的解析,但问题是 - 它不允许验证,即判断整个事情是否有效。

【问题讨论】:

  • @WiktorStribiżew 那里没有答案可以支持 URL 的所有部分都是可选的,根据我的示例。
  • 我不认为正则表达式是解决这个问题的好主意。为什么不直接手动解析 URL,然后构造所需的对象呢?
  • 为什么要在这种情况下使用正则表达式?为什么不用这个函数,比如这个:locutus.io/php/url/parse_url
  • @SergeyKhalitov 我不知道它是否有效,如果它在我描述的条件下有效,它会给出答案,而不是我为什么不使用它的问题 - 因为我显然,以前从未见过。

标签: javascript regex


【解决方案1】:

这样的?

function url2obj(url) {
    var pattern = /^(?:([^:\/?#\s]+):\/{2})?(?:([^@\/?#\s]+)@)?([^\/?#\s]+)?(?:\/([^?#\s]*))?(?:[?]([^#\s]+))?\S*$/;
    var matches =  url.match(pattern);
    var params = {};
    if (matches[5] != undefined) { 
       matches[5].split('&').map(function(x){
         var a = x.split('=');
         params[a[0]]=a[1];
       });
    }

    return {
        protocol: matches[1],
        user: matches[2] != undefined ? matches[2].split(':')[0] : undefined,
        password: matches[2] != undefined ? matches[2].split(':')[1] : undefined,
        host: matches[3],
        hostname: matches[3] != undefined ? matches[3].split(/:(?=\d+$)/)[0] : undefined,
        port: matches[3] != undefined ? matches[3].split(/:(?=\d+$)/)[1] : undefined,
        segments : matches[4] != undefined ? matches[4].split('/') : undefined,
        params: params 
    };
}

console.log(url2obj("protocol://user:password@hostname:12345/segment1/segment2?p1=val1&p2=val2"));
console.log(url2obj("http://hostname"));
console.log(url2obj(":password@"));
console.log(url2obj("?p1=val1"));
console.log(url2obj("ftp://usr:pwd@[FFF::12]:345/testIP6"));

正则表达式模式here on regex101的测试

【讨论】:

  • 这是一个绝妙的答案,谢谢!到目前为止我遇到的唯一问题 - 当它是 IPv6 时,它无法正确识别 host/hostname,对于 URL-s,它在方括号内指定,如下所示:[12ab:1234::],可以短至 @ 987654326@,最长 45 个字符。
  • 没关系,我自己修好了。再次,很好的答案,谢谢!
  • @vitaly-t 哦,对了,要从主机获取主机名,: 上有一个拆分,这会给 IP6 提供错误的结果,因为那些包含该字符。我猜你想出了如何从捕获组 3 中提取整个 IP6。顺便说一句,我稍微调整了正则表达式。
  • 上面提供的答案证明对将connection-string 定型为今天的强大模块非常有价值:) 再次感谢您!
  • @vitaly-t 呵呵,太棒了。好工作! :) 顺便说一句,对答案投票的人很少会展示他们用它做了什么。所以这让我笑了。
猜你喜欢
  • 2011-09-02
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-26
  • 1970-01-01
相关资源
最近更新 更多