一个小伙

啃个正则骨头--Url解析

2018.08.27

正则表达式是用于匹配字符串中字符组合的模式。在 JavaScript 中,正则表达式也是对象。这些模式被用于 RegExp 的 exec 和 test 方法, 以及 String 的 match、replace、search 和 split 方法。

前言

 正则这种东西是一个让我头疼的东西,真是书到用时方恨少,平常写的不多。但是真的到用的时候真的能大大提高生产力。

以解析 Url 参数为例: https://wangcch.cc?key1=demo1&key2=demo2 目标解析为{key1: “demo1”, key2: “demo2”}

思路

  1. 提取键值对
  2. 分离键值

 提取键值

var url = "https://wangcch.cc?key1=demo1&key2=demo2";

 首先在字符串中我们需要的的是key1=demo1&key2=demo2, 当然我们可以先以?分割字符串,再匹配[string]=[string]这种类型。

url.split("?")[1];
// key1=demo1&key2=demo2

匹配[string]=[string]时,&可以分离减值对。当然如果区分&,不如  也将?带上。 识别?/&为键值对开头。

 思路: [&|?][string]=[string] 

url.match(/[\&|\?]\w+\=\w+/g);
// ["?key1=demo1", "&key2=demo2"]

/**
 * \w    匹配一个单字字符(字母、数字或者下划线
 * \w+   匹配多个 \w,类似 \w{1,}
 * g     全局搜索
 */

去除键值对前的?|&:

url.match(/[\&|\?]\w+\=\w+/g).map(item => item.replace(/^[\&|\?]/g, ""));
//  ["key1=demo1", "key2=demo2"]

/**
 * ^     匹配输入的开始,输入字符串开始的位置。
 */

 分离键值

通过上述,已经提取了想要的键值数据: [“key1=demo1”, “key2=demo2”]。 接下来就是分离键值,目标:{key1: “demo1”, key2: “demo2”}

=分割键值:

url
  .match(/[\&|\?]\w+\=\w+/g)
  .map(item => item.replace(/^[\&|\?]/g, "").splice("="));

// [["key1", "demo1"], ["key2", "demo2"]] 二维数组

格式化,返回键值对对象

var obj = {};
url
  .match(/[\&|\?]\w+\=\w+/g)
  .map(item => item.replace(/^[\&|\?]/g, "").split("="))
  .map(arr => (obj[arr[0]] = arr[1]));

// obj: {key1: "demo1", key2: "demo2"}

最后 

const parsingURL = url => {
  let obj = {};
  url
    .match(/[\&|\?]\w+\=\w+/g)
    .map(item => item.replace(/^[\&|\?]/g, "").split("="))
    .map(arr => (obj[arr[0]] = arr[1]));
  return obj;
};

当然引 qs 库也许更快:

const { parse } = require("qs");
const parsingURL = url => {
  return parse(url.split("?")[1]);
};

// 面对复杂情况恐怕也好要好好写
const parsingURL = url => {
  return url.split("?")[1]
    ? parse(
        url
          .split("?")[1]
          .match(/\&?\w+\=\w+/g)
          .join("")
      )
    : {};
};

MDN:正则表达式