【JavaScript】正则表达式

转义字符

  1. 转义符号 \
  2. 转义字符 \字符
  • 想用单引号包裹单引号,可以转义 \'
let str = '你非常\'优秀\'';
console.log(str); // 你非常'优秀'
  • 如果想显示 \,可以转义 \\
let str = '你非常\\优秀\\';
console.log(str); // 你非常\优秀\
  • 一些规定好的转义字符:\n 换行;\t 制表符;\r 回车

正则表达式

  • 正则表达式是字符串的一种匹配模式,为简化字符串操作而生
  • 说白了就是检索字符串中特定字符的规则
  • 正则并不是单纯的字符串,而是一种逻辑公式

创建正则表达式

1. 构造函数创建:let reg = new RegExp();

JS 提供了一个内置构造函数 RegExp() (regular expression),用来创建正则表达式

let reg = new RegExp(); // 实例化一个正则对象
console.log(reg); // /(?:)/
  • 参数1:正则的规则
  • 参数2:修饰符 i m g
let reg = new RegExp('text');
let str1 = 'This is a text';
let str2 = 'This is a apple';
console.log(reg.test(str1), reg.test(str2)); // true false
  • test() → 判断字符串中,是否包含匹配正则的子字符串
  • 在该例中的效果,类似 includes()
2. 字面创建:let reg = //;
let reg = /text/;
let str1 = 'This is a text';
let str2 = 'This is a apple';
console.log(reg.test(str1), reg.test(str2)); // true false
特殊情况
  • 一般情况下,推荐使用字面量创建
  • 但对于字符串变量,只能使用构造函数创建
let str = 'text';
let reg1 = /str/; // /str/
let reg2 = new RegExp(str); // /text/

正则的方法

test()

用于判断字符串参数,是否有匹配正则规则的子字符串

  • 格式:reg.test(str);
  • str:需要判断的字符串
  • 返回布尔值,匹配成功返回 true,否则返回 false
let reg = /super/;
let str = 'hello superman';
console.log(reg.test(str)); // true
exec()

不管是不是全局匹配,都只在 str 中进行一次匹配,提取匹配成功的子字符串

  • 格式:reg.exec(str);
  • str:需要查询的字符串
  • 返回一个数组,存放与匹配文本有关的信息;如果没有找到匹配的文本,则返回 null
let reg = /super/;
let str = 'hello superman superman aaa';
let result = reg.exec(str);
console.log(result);
// ["super", index: 6, input: "hello superman superman aaa", groups: undefined]
  • result[0]:匹配文本
  • result.index:匹配文本的首字符的位置
  • result.input:被检索的字符串 str

字符串的方法

字符串的 match() 方法

match() 将检索字符串 str,寻找 1~ n 个与 reg 匹配的文本;并返回指定的值

  1. 如果 reg 没有 g

reg.exec(str); 等效

let reg = /super/;let str = 'hello superman superman aaa';let result = str.match(reg);console.log(result);// ["super", index: 6, input: "hello superman superman aaa", groups: undefined]
  1. 如果 regg

match() 方法将执行全局检索,找到 str 中的所有匹配子字符串。

  • 返回值 result:若没有找到任何匹配的子串,则返回 null;否则,返回一个数组,存放所有的匹配子串,而没有 index / input 属性
let reg = /super/g;let str = 'hello superman superman aaa';let result = str.match(reg);console.log(result); // ["super", "super"]
字符串的 search() 方法

从前往后查询指定字符串第一次出现的位置 ( 1个参数 )

let reg = /super/;let str = 'hello superman superman aaa';console.log(str.search(reg)); // 6
字符串的 split() 方法

字符串 → 数组

let reg = /super/;let str = 'hello superman superman aaa';console.log(str.split(reg)); // ["hello ", "man ", "man aaa"]
字符串的 replace() 方法

实现字符串的替换

let reg = /man/g; // 后面加 g,可以实现全部替换let str = 'hello superman superman aaa';console.log(str.replace(reg, 'women')); // hello superwomen superwomen aaa

修饰符

  • i:不区分大小写 ignoreCase
  • m:换行匹配 multiline
  • g:全局匹配 global
i:不区分大小写 ignoreCase

默认区分大小写

let reg = /Text/;
let str = 'This is a text';
console.log(reg.test(str)); // false
let reg = /Text/i; // 字面量写法
let str = 'This is a text';
console.log(reg.test(str)); // true
m:换行匹配 multiLine

默认不是换行匹配

let reg = new RegExp('^Text');
let str = 'This is a \nText and';
console.log(str.match(reg)); // null
let reg = new RegExp('^Text', 'm'); // 构造函数写法
let str = 'This is a \nText and';
console.log(reg.exec(str));
// ["Text", index: 11, input: "This is a \nText and", groups: undefined]
g:全局匹配 global

默认只匹配一个

let reg = new RegExp('text');
let str = 'This is a text and text and text';
console.log(str.match(reg));
// ["text", index: 10, input: "This is a text and text and text", groups: undefined]
let reg = new RegExp('text', 'g');
let str = 'This is a text and text and text';
console.log(str.match(reg));
// ["text", "text", "text"]

特殊语法

特殊字符

  • 正则表达式 = 普通字符 + 特殊字符(元字符)
  • 普通字符:字母(abcABC)、数字(123)、_$
  • 特殊字符:()[]{}^$*?\|+.
  • 普通字符可以直接使用
  • 特殊字符要转义,因为特殊字符在正则中有特殊意义
// 匹配 ^a
let reg = /\^a/g; // ^ 有特殊意义,需要转义
let str = 'bb^acc';
console.log(str.match(reg)) // ["^a"]

预定义的特殊字符

  • \t:制表符
  • \n:回车符
  • \f:换页符
  • \b:回退字符
// 匹配制表符
let str = 'a\tb';
let reg = /\t/;
console.log(str); // a	b
console.log(reg.test(str)); // true
// 匹配回车符
let str = `a\nb`;
let reg = /\n/;
console.log(str)
console.log(reg.test(str)); // true

字符集

简单类

通过 [] 包裹住,来表示这几个字母组成的一个简单集合

如:[abDF45] 表示由 abDF45 6 个字符组成的一个集合

let str = 'abcdefg';
let reg = /[bgk]/;
console.log(str.match(reg));
// ["b", index: 1, input: "abcdefg", groups: undefined]

str 中,找到第 1 个在集合 [bgk] 中的字符

范围类

通过 小字符-大字符 组成的一个范围集合;大小指的是 ASCII 码大小

如:[a-z] 表示小写字母集合、[A-Z] 表示大写字母集合、[0-9] 表示数字集合

let str = 'abcdefg';
let reg = /[f-i]/g;
console.log(str.match(reg)); // ["f", "g"]

要按照字符编码集从小到大写,eg:[A-z];不能从大到小写,eg:[a-Z]

负向类

[] 内部添加 ^ 前缀,表示不包含该集合的字符集

如:[^abc] 表示不包含 abc 的集合,[^ab89CD] 表示不包含 ab89CD 这 6 个字符的集合

let str = 'abcdef';
let reg = /[^abc]/g;
console.log(str.match(reg)); // ["d", "e", "f"]
组合类

将几个集合拼接在一起,表示一个组合的集合

如:[a-zA-Z0-9] 表示大小写字母以及数字的集合

let str = '0';
let reg = /[0-9a-z]/;
console.log(reg.test(str)); // true
注意
  1. [] 内,无论写多少个字符,只会匹配其中一个
  2. 特殊的字符集:[\u4e00-\u9fa5] 表示中文集

界定符

字符串有边界,这里的边界指的就是字符串的首尾

判断前后缀

判断前缀用 ^,如:/^abc/ 判断字符串的前缀是否为 abc

判断后缀用 $,如:/xyz$/ 判断字符串的后缀是否为 xyz

let str = 'sdf';
let reg = /^b/;
console.log(reg.test(str)); // false
匹配后面跟的字符

(?=n):匹配到后面跟着字符 n 的字符串

(?!n):匹配到后面没有紧跟着字符 n 的字符串

let str = "abcd";
let reg = /c(?=d)/; // 找到后面跟着 d 的字符 c
console.log(str.match(reg));
// ["c", index: 2, input: "abcd", groups: undefined]

预定义的类(元字符)

就是特殊的转义字符,把一些字母转成特殊意义的字符

  • .[^\n\r]:除了换行和回车之外的任意字符
  • \d[0-9]:数字字符( digit 数字 )
  • \D[^0-9]:非数字字符
  • \s[\t\n\f\r]:空白字符
  • \S[^\t\n\f\r]:非空白字符
  • \w[a-zA-Z_0-9]:字母
  • \W[^a-zA-Z_0-9]:非字母
let str = 'sdf';
let reg = /\W/;
console.log(reg.test(str)); // false

量词

  • 用于设置匹配到字符的个数

  • 默认贪婪匹配,即尽量往指定范围大的匹配;在量词后加 ?,则变为惰性匹配,即尽量往指定范围小的匹配

  • 重复书写某个规则时,可以用量词代替。eg:匹配 10 个数字,/\d\d\d\d\d\d\d\d\d\d//\d{10}/

量词普通写法
  • {n}:n 个
  • {n,m}:n ~ m 个,[n, m],是个闭区间
  • {n,}:n ~ 无穷大个,包含 n
let str = 'a b a bb a bbb a bbbb';
let reg1 = /b{2,4}/g; // 贪婪匹配
let result1 = str.match(reg1);
console.log(result1); // ["bb", "bbb", "bbbb"]

let reg2 = /b{2,4}?/g; // 惰性匹配
let result2 = str.match(reg2);
console.log(result2); // ["bb", "bb", "bb", "bb"]
量词特殊写法
  • {0,1}?
  • {0,}*
  • {1,}+
let str = 'ababba';
let reg1 = /b?/g;
let result1 = str.match(reg1);
console.log(result1); // ["", "b", "", "b", "b", "", ""]

let reg2 = /b*/g;
let result2 = str.match(reg2);
console.log(result2); // ["", "b", "", "bb", "", ""]

let reg3 = /b+/g;
let result3 = str.match(reg3);
console.log(result3); // ["b", "bb"]

子项

可以用 () 将部分正则括住,这样在使用 match / exec 做匹配时,能获取指定字符开头的数据

let str = "abcd12ef";
let reg = /d(\d+)/; // 获取 d 后面的数字
let result = str.match(reg);
console.log(result); // ["d12", "12", index: 3, input: "abcd12ef", groups: undefined]
console.log(result[1]); // 12

注意:加全局匹配 g 后,match 方法就不包含子项了

子项的反引用

格式:\numnum 为子项的序号

let str = "ccsdbbcc99d";
let reg = /([a-z])\1/g; // 获取连续写了两遍的字母
let result = str.match(reg);
console.log(result); // ["cc", "bb", "cc"]

上面 \1 表示复用第 1 个子项 [a-z]

或者 |

  1. 在正则中,| 表示或者
let str = "adcd12ef";
let reg = /ad|cd/g;
console.log(str.match(reg));  // ["ad","cd"]

可以与子项结合使用:

let str = "adcd12ef";
let reg = /(a|c)d/g;
console.log(str.match(reg));  // ["ad","cd"]
  1. 如果 | 放在字符集里,表示普通的竖线
let str = "adcd1|d2ef";
let reg = /[a|c]d/g;
console.log(str.match(reg));  // ["ad", "cd", "|d"]

[a|c] 表示 a|b 中的一个

案例

  1. 手机号:11位、第一位是1、都是数字
let reg = /^1\d{10}$/;
let str = prompt('请输入手机号');
if (reg.test(str)) {
    console.log('成功');
} else {
    console.log('失败');
}
  1. QQ 邮箱:
let eMail = /^\d{6-10}@q{2}\.com$/;

. 在正则中有特殊意义,所以需要转义

  1. 日期格式转换:
function formatDate(date, fmt) {
    // 年
    let reg = /Y+/;
    if (reg.test(fmt)) {
        let str = fmt.match(reg)[0];
        fmt = fmt.replace(str, (date.getFullYear() + '').substr(4 - str.length));
    }

    // 月日时分秒
    let obj = {
        'M+': date.getMonth() + 1,
        'D+': date.getDate(),
        'h+': date.getHours(),
        'm+': date.getMinutes(),
        's+': date.getSeconds()
    }
    for (let key in obj) {
        let reg = new RegExp(key);
        if (reg.test(fmt)) {
            let str = fmt.match(reg)[0];
            fmt = fmt.replace(str, toTwo(obj[key]));
        }
    }

    return fmt;
}

function toTwo(num) {
    return (num > 10 ? '' : '0') + num;
}

let date = new Date();
let result = formatDate(date, 'YYYY-MM-DD hh:mm:ss');
console.log(result);
上一篇:正则表达式


下一篇:利用 Flask 动态展示 Pyecharts 图表数据的几种方法