「✍ 正则表达式」

179 阅读2分钟

1 - 提取url中的参数

url = https://baidu.com?a=123&b=123&c=123

匹配其中的参数b

url.match(/[\?&]b=[^&]*/g)

[\?&]: 开头,因为参数可能在第一个,因此可能是?&

b=[^&]*:从b=开始匹配不等于&的字符,遇到&或后面为空为止

/**
 * remove any param in url
 * @param url
 * @param key
 * @returns {string} url after remove param
 */
const removeUrlParam = (url: string, key: string): string => {
  let reg = new RegExp("[\\?&]" + key + "=[^&]*", "g"); // \? 要写成 \\? 转义一下
  return url.replace(reg, "");
};

2- 下划线和驼峰的转换

下划线转驼峰

const lineToHump = (str: string): string => {
  let s = str.replace(/_(\w)/g, (res, char) => {
    return char.toUpperCase();
  });
  return s;
};

驼峰转下划线

const humpToLine = (str: string): string => {
  let s = str.replace(/([A-Z])/g, (res) => {
    return "_" + res.toLowerCase();
  });
  return s;
};

两种转换都是对replace和正则的运用,复习一下replace的参数

stringObject.replace(regexp/substr,replacement)

regexp/substr : 规定子字符串或要替换的模式的 RegExp 对象。

replacement 一个字符串值或规定了替换文本或生成替换文本的函数

当replacement被作为函数传入, 每次匹配都会调用,其参数如下

(result, c1, c2 ... cn, index, str) => string

result : 当次匹配到的字符串

c1 - cn : result 可简单理解为第n每个分组,即用 第n个用()包裹的字串

index: 当次匹配发生的下标

str: stringObject 本身

1.下划线转驼峰

"hello_world_fk" .replace(/_(\w)/g, (result, char) => {
  return char.toUpperCase();
});

/_(\w)/g会匹配三次,result为 _w _d _f, char即为分组(\w)即为w d f

2.驼峰转下划线

"helloWorldFk". replace(/([A-Z])/g, (result) => {
  return "_" + result.toLowerCase();
});

也有更简便的解法

replace(/([A-Z])/g,"_$1").toLowerCase();

$n: 模式匹配到的第n个分组

3- 调换字符串顺序

/**
 * reverse first name and last name
 * @param name
 * @returns {string} name after reverse
 */
const reverseName = (name: string): string => {
  let reg = new RegExp("(\\w+)\\s(\\w+)", "g"); // 字符串中 \w 要写成 \\w 转义一下
  
  return name.replace(reg, "$2 $1");

  // or
  return name.replace(reg, (result, group1, group2) => {
    return group2 + " " + group1;
  });

  // or
  return name.replace(/(\w+)\s(\w+)+/g, (result, group1, group2) => {
    return group2 + " " + group1;
  });
};

reverseName("hello liu") // liu hello

4- 反向预查和正向预查

正向预查:?=

(?=\>)表示\>仅用于匹配前面的结果,不用于输出

反向预查:?<=

(?<=\<)表示\<仅用于匹配后面的结果,不用于输出

如我们需要提取 <div><br>中的标签名,且不含<>

reg = /(?<=\<)[^<>]*(?=\>)/g

其中,[^<>]*表示匹配任何不为<>的字符

5- 校验url正确性

以m.com为例, 符合校验规则的有

http(s)://m.com

http(s)://m.com?a=1

http(s)://m.com?a=1&b=2

let reg = /^https?:\/\/m\.com(\?(\w+\=\w+(\&\w+\=\w+)*)+)?$/