360前端星计划—正则的三个应用场景

本文章目录:

  1. 正则表达式的创建和使用
  2. 场景一:正则与数值
  3. 场景二:正则与颜色
  4. 场景三:正则与URL

正则表达式的创建和使用

一、创建正则表达式的两种方式

  1. 使用正则表达式字面量

    const reg = /[a-z]\d+[a-z]/i
    

    优点:简单方便;无需二次转义

    缺点:子内容无法重复使用;过长的正则导致可读性变差

  2. 使用**RegExp**构造函数

    const alphabet = '[a-z]';
    const reg = new RegExp(`${alphabet}\\d+${alphabet}`, 'i');
    

    优点:子内容可以重复使用;可以通过控制子内容的粒度提高可读性

    缺点:二次转义的问题容易导致BUG, 如:

    const reg = new RegExp(`\d+`);
    reg.test('1'); // false
    reg.test('ddd'); // true
    

二、正则表达式的常见用法

  1. RegExp.prototype.test()

    判断某个字符串(若输入不是字符串,会尝试类型转换,转换失败则抛出TypeError)是否匹配正则表达式。若匹配,返回true,否则返回false

    const reg = /[a-z]\d+[a-z]/i;
    
    reg.test('a1a'); //true
    reg.test('1a1'); //false
    reg.test(Symbol('a1a')); // TypeError
    
  2. RegExp.prototype.sourceRegExp.prototype.flags

    分别返回当前正则表达式的模式文本字符串和当前正则表达式的修饰符的字符串(对修饰符按照字母升序排列:gimsuy)

    const reg = /[a-z]\d+[a-z]/ig;
    
    reg.source; // "[a-z]\d+[a-z]"
    reg.flags; // "gi"
    
  3. RegExp.prototype.exec()String.prototype.match()

    输入:

    前者要求输入字符串,遇到非字符串类型会尝试类型转换。

    后者要求输入正则表达式,遇到其他类型会先尝试转换为字符串,再以字符串为source创建正则表达式

    输出:匹配成功返回匹配结果。匹配失败返回null

    const reg = /[a-z]\d+[a-z]/i;
    
    reg.exec('a1a'); // ["a1a", index: 0, input: "a1a", groups: undefined]
    reg.exec('1a1'); // null
    'a1a'.match(reg); // ["a1a", index: 0, input: "a1a", groups: undefined]
    '1a1'.match(reg); // null
    

    当正则表达式含有g修饰符时,RegExp.prototype.exec()每次只返回一个匹配结果,数据格式与不含g修饰符相同。

    String.prototype.match()会返回所有匹配结果,数据格式会变为字符串数组。

  4. RegExp.prototype.lastIndex

    当前正则表达式最后一次匹配成功的位置(也是下一次匹配开始的位置)

    const reg = /(a)/g;
    const str = 'a1a';
    
    reg.lastIndex; // 0
    reg.exec('a1a'); // ["a", "a", index: 0, input: "a1a", groups: undefined]
    reg.lastIndex; // 1
    reg.exec('a1a'); // ["a", "a", index: 2, input: "a1a", groups: undefined]
    reg.lastIndex; // 3
    reg.exec('a1a'); // null
    reg.lastIndex; // 0
    

    lastIndex不会自己重置,只有当匹配失败了只会才会重置为0。因此每次匹配之后都需要手动重置lastIndex

  5. String.prototype.replace()String.prototype.search()String.prototype.split()

场景一:正则与数值

一、 一个完整的匹配数值的正则表达式

/^[+-]?(?:\d+\.?|\d*\.\d+)(?: e[+-]?\d+)?$/i
  • ^:匹配字符串的开始位置
  • $:匹配字符串的结束位置
  • ():圆括号内为一个子表达式,当圆括号不带任何修饰符时,表示同时创建一个捕获组
  • ?:匹配0或1个
  • .:匹配除换行符之外的任意字符,因此匹配小数点字符时需要转义
  • (?😃:创建一个非捕获组
  • *****:匹配0或多个
  • +:匹配1或多个
  • i修饰符:忽略大小写

二、用正则处理数值

  1. 数值的解析

    const reg = /[+-]?(?:\d*\.)?\d+(?:e[+-]?\d+)?(?=px|\s|$)/gi;
    
    function execNumberList(str) {
        reg.lastIndex = 0; //重置正则表达式的lastIndex
        let exec = reg.exec(str);
        const result = [];
        while (exec) {	//将所有匹配所得数字加入result中
            result.push(parseFloat(exec[0]));
            exec = reg.exec(str);
        }
        return result;
    }
    
    console.log(execNumberList('1.0px .2px -3px +4e1px')); // [1, 0.2, -3, 40]
    console.log(execNumberList('+1.0px -0.2px 3e-1px')); // [1, -0.2, 0.3]
    console.log(execNumberList('1px 0')); // [1, 0]
    console.log(execNumberList('-1e+1px')); // [-10]
    
    • g修饰符:表示全局匹配
    • (?=expression):匹配下一个表达式为expression的位置
  2. 数值转为货币

    const reg = /(\d)(?=(\d{3})+(,|$))/g;
    function formatCurrency(str) {
       return str.replace(reg, '$1,');
    }
    
    console.log(formatCurrency('1')); // 1
    console.log(formatCurrency('123')); // 123
    console.log(formatCurrency('12345678')); // 12,345,678
    
    • {n}:表示重复n次
    • {n,m}:重复n到m次
    • {n,}:重复至少n次
    • $n:用于replace的字符串中,表示第n个捕获组。n可以为从1到9

场景二:正则与颜色

一、颜色的表示方式

  1. 16进制表示法,如 #fff、#abceee、#15573
  2. rgb/rgba表示法,如 rgb(r, g, b)、rgb(r%, g%, b%)
  3. 其他

二、使用正则处理颜色

16进制颜色优化

const hex = '[0-9a-z]';
const hexReg = new RegExp(`^#(?<r>${hex})\\k<r>(?<g>${hex})\\k<g>(?<b>${hex})\\k<b>(?<a>${hex}?)\\k<a>$`, 'i');
function shortenColor(str) {
    return str.replace(hexReg, '#$<r>$<g>$<b>$<a>');
}

console.log(shortenColor('#336600')); // '#360'
console.log(shortenColor('#19b955')); // '#19b955'
console.log(shortenColor('#33660000')); // '#3600'

场景三:正则与URL

一、用正则解析URL

const protocol = '(?<protocol>https?:)';
const host = '(?<host>(?<hostname>[^/#?:]+)(?::(?<port>\\d+))?)';
const path = '(?<pathname>(?:\\/[^/#?]+)*\\/?)';
const search = '(?<search>(?:\\?[^#]*)?)';
const hash = '(?<hash>(?:#.*)?)';
const reg = new RegExp(`^${protocol}\/\/${host}${path}${search}${hash}$`);
function execURL(url) {
    const result = reg.exec(url);
    if (result) {
        result.groups.port = result.groups.port || '';
        return result.groups;
    }
    return {
        protocol: '', host: '', hostname: '', port: '',
        pathname: '', search: '', hash: '',
    };
}

console.log(execURL('https://www.360.cn'));
console.log(execURL('http://localhost:8080/?#'));
console.log(execURL('https://image.so.com/view?q=360&src=srp#id=9e17bd&sn=0'));
console.log(execURL('this is not a url'));

二、用正则解析hash和search

function execUrlParams(str) {
    str = str.replace(/^[#?&]/, '');
    const result = {};
    if (!str) {
        return result;
    }
    const reg = /(?:^|&)([^&=]*)=?([^&]*?)(?=&|$)/y;
    let exec = reg.exec(str);
    while (exec) {
        result[exec[1]] = exec[2];
        exec = reg.exec(str);
    }
    return result;
}

console.log(execUrlParams('#')); // { }
console.log(execUrlParams('##')); // { '#': '' }
console.log(execUrlParams('?q=360&src=srp')); // { q: '360', src: 'srp' }
console.log(execUrlParams('test=a=b=c&&==&a=')); // { test: 'a=b=c', '': '=', a: '' }

Node.js基础入门

什么是Node.js

Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.

与JavaScript的区别

  • 基于异步I/O相关接口
  • 基于 node_modules 和 require 的模块依赖
  • 提供 C++ addon API 与系统交互

Node.js基础

模块
  • 内置模块:编译进Node中,比如httpfsnetprocesspath
  • 文件模块:原生模块之外的模块,和文件(夹)一一对应。

一个使用内置模块的例子:

const fs = require('fs');
fs.readFile('a.txt', (err, buffer) => {
    console.log(buffer);
});
//或者
const { readFile } = require('fs');
readFile('a.txt', (err,buffer) => {
    console.log(buffer);
});

一个使用文件模块的例子:

//app.js
var circle = require('./circle.js');
console.log('半径为4的圆面积是:' + circle.area(4));

//circle.js
const pi = Math.PI;
exports.area = function(r) {
    return pi * r * r;
};
exports.circumference = function(r) {
    return 2 * pi * r;
};

加载模块的方法:

//绝对路文件
require('/foo/bar/a.js');

//相对路径文件
require('./a.js');

//无后缀文件
require('./a');

//外部模块
require('pkg-name');
Node.js Web开发
  1. API开发 使用RESTful API

    RESTful API接口规范

    1. 每个API都对应一种资源或者资源集合
    2. 使用HTTP Method来表示对资源的动作
    3. 使用HTTP Status Code来表示资源操作结果
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值