正则表达式

一、基础

具体参考
正则字符模式
30分钟入门

定义:
RegExp:regular expression
正则匹配原则

  • 1、连续匹配,字符串从左到右,依次先匹配多,再匹配少,如果一旦匹配上就不回头匹配;
  • 2、贪婪模式:能匹配上多个,绝不匹配少个
  • 3、? 将贪婪改为非贪婪模式

1、两种数组声明方式

// 字面量 
const reg = //;
const pattern = /test/;
// RegExp对象
const pattern = new RegExp("test");

// 使用说明
当正则表达式在开发环境是明确的,推荐优先使用字面量语法;
当需要在运行时动态创建字符串来构建正则表达式时,则使用构造函数的方式

2、5种修饰符

修饰符 说明
i ignore case,对大小写不敏感的匹配,即忽略大小写
g global,全局匹配
m multi-line,多行匹配,比如针对textarea的匹配
y sticky,开启粘连匹配。正则表达式执行粘连匹配时试图从最后一个匹配的位置开始
u unicode,允许使用Unicode点转义符(\u{…})

3、范围查找

[]   表达式可匹配范围,即查找方括号之间的任何字符
[abc]        匹配a、b、c中的任意一个字符
[0-9]        查找任何从 0 至 9 的数字
(x|y)        查找任何以 竖线 分隔的选项

-        短横线,区间符号
^        非(在区间匹配中),字符开头(作为正则第一个字符开头时)
|        或
$        结尾符号
\         转义字符

示例:
[^abc]        表示匹配除了a、b、c以外的任意字符
[a-m]        匹配a和m之间的小写字母
/^test$/        匹配test字符

4、元字符

元字符 说明
\w 匹配任何字母、数字和下划线,等价于[A-Za-z0-9_]
\W 匹配除了字母、数字和下划线之外的字符,等价于[^A-Za-z0-9_] 和 [^\w]
\d 匹配任意十进制数字,等价于[0-9]
\D 匹配除了十进制数字外的任意字符,等价于[^0-9] 和 [^\d]
\s 匹配任意空白字符,包括空格、制表符、换页符等。等价于[\r\n\t\v\f]
\S 匹配除空白字符外的任意字符,等价于 [^ \f\n\r\t\v] 和 [^\s]
\b 匹配单词边界
\B 匹配非单词边界(单词内部)
. 匹配除换行符(\n、\r)之外的任何单个字符。
. 要匹配包括 ‘\n’ 在内的任何字符,请使用像”(.竖线\n)”的模式
\r 回车符
\n 换行符
\t 水平制表符 tab
\v 垂直制表符
\f 换页符

5、量词

量词 说明
n+ {1, 正无穷},匹配包含1次或多次 n 的字符串
n* {0, 正无穷},匹配包含1次或多次 n 的字符串
n? {0, 1},匹配包含0次或1次 n 的字符串
{n} 匹配重复n次
{n, } 匹配n个到多个

6、子表达式 反向引用

()        子表达式,具有记忆功能
\n        反向引用第n个表达式

示例:
// 取出aaaa  xxxx
var str = 'bbaaaaccaaaaiddddbaaaa',
    reg = /(a)\1\1\1/g;
    reg1 = /(\w)\1\1\1/g;

// 取出xxyy
var str = 'aabbccdddddccceevv',
    reg = /(\w)\1(\w)\2/g;

7、JS 正则三种方法
test, exec, match, replace

二、示例

// replace(需要替换的字符, 替换字符)
// 不具备全局匹配能力
var str = 'JSplusplus';
var str1 = str.replace('plus', '+');
console.log(str1); // 'JS+plus'

var reg = /plus/;
var str1 = str.replace(reg, '+');
console.log(str1); // 'JS+plus'

// 全局
var reg = /plus/g;
var str1 = str.replace(reg, '+');
console.log(str1); // 'JS++'

// xxyy -> yyxx
var str = 'aabbcccdd',
    reg = /(\w)\1(\w)\2/g;

// 方法一
var str1 = str.replace(reg, '$2$2$1$1'); // $拿子表达的反向引用
console.log(str1); // 'bbaaddcc'

// 方法二
var str1 = str.replace(reg, function($, $1, $2){
    // $ 当次被匹配的值
    // $1 子表达式1
    // $2 子表达式2
    return $2 + $2 + $1 + $1;
});


// js-plus-plus -> jsPlusPlus
var str = 'js-plus-plus',
    reg = /-(\w)/g;

var str1 = str.replace(reg, function($, $1){
    return $1.toUpperCase();
});

// jsPlusPlus -> js-plus-plus
var str = 'jsPlusPlus',
    reg = /([A-Z])/g;

var str1 = str.replace(reg, function($, $1){
    console.log($, $1);
    return '_' + $1.toLowerCase();
});

// xxyyzz -> XxYyZz
var str = 'xxyyzz',
    reg = /(\w)\1(\w)\2(\w)\3/g;

var str1 = str.replace(reg, function($, $1, $2, $3){
    return $1.toUpperCase() + $1 + $2.toUpperCase() + $2 + $3.toUpperCase() + $3;
});


// aabbcc -> a$b$c$ 不能使用function
var str = 'aabbcc',
    reg = /(\w)\1(\w)\2(\w)\3/g;

var str1 = str.replace(reg, '$1$$$2$$$3$$'); // 用两个$$ -> $

// 语法中存在的字符,需要用 \ 转义
var str = 'aa\\bb\\cc',
    reg = /\\/g;

// \B 非单词边界
var str = '100000000000';
var str1 = str.replace(/(\d{3}\B)/g, '$1,'); // '100,000,000,000'

var str = '10000000000';
var str1 = str.replace(/(?=(\B)(\d{3})+$)/g, ','); // '10,000,000,000'


// 双大括号替换值
var str = 'My name is {{name}}, I\'m {{age}} years old',
    reg = /{{(.*?)}}/g;

var str1 = str.replace(reg, function(node, key){
    console.log(node, key);

    return {
        name: 'Jone',
        age: 32
    }[key];
});