正则表达式

338 阅读4分钟

语法

在JavaScript中,正则表达式也是对象,是一种索引类型。 使用一个正则表达式字面量是最简单的方式。两个/是则表达式的定界符。 你可以通过下面两种方法创建一个正则表达式:

  • 使用一个正则表达式字面量,如下所示:
// 常用
var reg=/abc/;

正则表达式字面量在脚本加载后编译。若你的正则表达式是常量,使用这种方式可以获得更好的性能。

  • 调RegExp对象的构造函数,如下所示:
var re=new RegExp("abc");

相关正则方法

  • 字符串的方法: 字符串.split() 根据匹配字符串切割父字符串
    字符串.match() 使用正则表达式与字符串相比较,返回一个包含匹配结果的数组。
    字符串.search() 对正则表达式或指定字符串进行搜索,返回第一个出现的匹配项的下标。
    字符串.replace() 用正则表达式和字符串直接比较,然后用新的子串来替换被匹配的子串。
  • 正则表达式方法: 正则.exec() 在目标字符串中执行一次正则匹配操作。
    正则.test() 测试当前正则是否能匹配目标字符串。
    字符串的方法:
// split 方法:分割字符串,成为一个数组
var str = "aa bbb    c dd eeeeee";
// 使用一个空格字符进行的精确分割
var arr = str.split(" ");
// 使用正则表达式可以进行模糊匹配分割,将连续的字符当成整体处理
var arr1 = str.split(/\s+/);
console.log(arr1);
var str2 = "bbaacaaaadddaeeeeeaaf";
var arr2 = str2.split(/a+/);
console.log(arr2);// 输出["aa","bb","c","dd","eeeeee"]
// search 方法:查询子串在父字符串中出现的位置,没找到就输出-1
var str = "abcdefg";
console.log(str.search("cdf"));//输出-1
console.log(str.search(/eff/));//输出-1
// match 方法:在父字符串中去匹配符合的子字符串,将结果输出到数组中
var str = "abbcccbbbbbddbbbdabbb";
var arr = str.match(/b+/);  //在匹配到第一个之后就结束
var arr = str.match(/b+/g); //如果有全局修饰符 g,会在找到所有匹配的字符串后结束
console.log(arr);
var str1 = "aaaa o  o bbb o     o  aaa";
var arr1 = str1.match(/o\s+o/g);
console.log(arr1);// 输出["o  o", "o     o"]
// replace 方法:替换字符串的指定部分,返回值是一个新的替换后的字符串,原始字符串不受影响
var str = "www.hello.com";
var str1 = str.replace(/hello/,"byebye");
console.log(str);
console.log(str1);

正则表达式方法:

// exec 方法:查找匹配的字符串,输出到数组中
// 不论有没有全局修饰符,都只会在找到第一个之后停止
var str = "aaaabccccbacabc";
var reg = /abc/;
var arr = reg.exec(str);
console.log(arr);
console.log(arr.index);
// test 方法:检测字符串中是否满足正则表达式的匹配规则,返回值是布尔值
var reg = /abc/;
console.log(reg.test("aaddccddabcddeeddfff"));

正则表达式的组成

由一些普通字符和一些特殊字符(又叫元字符--metacharacters)组成。普通字符包括大小与 的字母和数字,而元字符则具有特殊的含义。 特殊字符: javascript中常特殊字符有() [] {} \ ^ $ | * + . 若想匹配这类字符必须用转义符号\如:\( , \^ ,\\

// 普通字符组成的正则
var reg = /abc/;
// 表示正则匹配时,需要进行精确匹配,必须包含a、b、c三个字符,并且顺序不能颠倒,而且要连续书写
console.log(reg.test("asldfjwefabcsld"));
// 特殊字符,匹配字符串中对应的普通的符号字符时,需要进行转义
var reg = /a\*/;
console.log(reg.test("alsdj*sd"));
// 预定义特殊字符
// 一些特殊的字符串不能在正则中直接书写相同的符号,所以正则中提供了一些替换写法
var reg = /\s/;
console.log(reg.test("  "));
// \n 表示的是回车符
var str = `sdlfkjw
eofoa`;// ``字符串中间可以包含换行符,而不报错
console.log(/\n/.test(str));

正则的术语

字符集

// 字符集:使用 [] 表示的可能的字符的集合,集合内部可以排列多个匹配字符串的可能性,
// 整个字符集需要匹配的是字符串中的一个字符。
// [] --> 字符串中的一个字符,多选一的效果,有一个满足就算匹配成功
// 简单类:多个可能匹配的字符连续书写在一起,只要其中一个匹配成功即可
var reg = /[abc]/;
console.log(reg.test("eeeb"));
// 范围类:将匹配同一类型且连续在一起的字符写到集合中,中间使用 - 连接
var reg = /[0-9]/;
var reg = /[a-z]/;
var reg = /[A-Q]/;
console.log(reg.test("A123456"));
// 负向类:取反的意思,不包含字符集内部书写的字符
var reg = /[^A-Q]/; // 不包含A-Q字符 
console.log(reg.test("A"));
// 组合类:单一类型或者简单类不能匹配所有结果,可以将多个写法连在一起书写
// 特殊的:如果数字、大写字母、小写字母,按照这种顺序写的完整的范围,可以缩写
var reg = /[0-9a-z]/;
var reg = /[0-9A-Z]/;
var reg = /[0-z]/;
console.log(reg.test("a"));

修饰符

  • g修饰符用于执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
  • i修饰符用于执行对大小写不敏感的匹配。
// g 修饰符:可以实现全局查找 
var str = "aabblsdddbbbdlBBdllbbbbb";
var reg = /b+/g;
console.log(str.match(reg));
// i 修饰符:字母大小写可以不敏感,a 可以匹配 a 或 A
var str = "aabblsdddbbbdlBBdllbbbbb";
var reg = /A/ig;
console.log(str.match(reg));// 输出[a,a]

边界

// 边界
// ^  表示限制开头,后面的正则内容匹配的结果必须出现在字符串开始
var str = "hello ll Javascript";
console.log(/^hello/.test(str));
console.log(/^hhello/.test(str));
// $ 表示限制结尾,前面的正则内容匹配的结果必须出现在字符串结尾
console.log(/script$/.test(str));
console.log(/scripthaha$/.test(str));
// 实际应用中,会同时限制开头和结尾
console.log(/^hello\s+Javascript$/.test(str));

预定义类

// 非回车非换行字符 .
console.log(/^.+$/.test(`asldjf2830&*^`));
console.log(/^.+$/.test(`asldjf
2830&*^`));
// \d 数字字符 \D 非数字字符
console.log(/^\d+$/.test(`0123456789`));
console.log(/^\d+$/.test(`01234z56789`));
console.log(/^\D+$/.test(`askdAK  *&^`));
console.log(/^\D+$/.test(`askdAK  *&^7`));
// \s 空白字符 \S 非空白字符
console.log(/^\s+$/.test(`  1    
`));
console.log(/^\s+$/.test(`      
`));
console.log(/^\S+$/.test(`AJO456`));
console.log(/^\S+$/.test(`AJO  456`));
// \w 单词字符 \W 非单词字符
console.log(/^\w+$/.test(`abc09_A`));
console.log(/^\w+$/.test(`abc*09_A`));
console.log(/^\W+$/.test(`*&^%$ *`));
console.log(/^\W+$/.test(`a*&^%$ *`));

量词

// 量词
// {n}  硬性量词   对应前面的内容必须在字符串中出现 n 次连续
var reg = /^\d{5}$/;
console.log(reg.test("1234"));
console.log(reg.test("12345"));
console.log(reg.test("123456"));
// {n,m}  软性量词  对应前面的内容必须在字符串中出现 n-m 次连续
var reg = /^\d{5,7}$/;
console.log(reg.test("1234"));
console.log(reg.test("12345"));
console.log(reg.test("123456"));
console.log(reg.test("1234567"));
console.log(reg.test("12345678"));
// {n,}  软性量词  对应前面的内容必须在字符串中出现至少 n 次连续
var reg = /^\d{5,}$/;
console.log(reg.test("1234"));
console.log(reg.test("12345"));
console.log(reg.test("123456"));
console.log(reg.test("1234567"));
console.log(reg.test("123456789101112"));
// ?  软性量词  {0,1} 表示前面的内容出现 0 次或 1次
var reg = /^\d?$/;
console.log(reg.test("1"));
console.log(reg.test(""));
console.log(reg.test("12345"));
// *  软性量词  {0,} 表示前面的内容出现 0 次或 任意次
var reg = /^\d*$/;
console.log(reg.test("1"));
console.log(reg.test(""));
console.log(reg.test("12345"));
// +  软性量词  {1,} 表示前面的内容出现 1 次或 以上
var reg = /^\d+$/;
console.log(reg.test(""));
console.log(reg.test("1"));
console.log(reg.test("12345"));

分组

虽然量词的出现,能帮助我们处理一排密紧密相迓的同类型字符。但这是不够的,我们用中括号表示范围内选择,大括号表示重复次数。如果想获取重复多个字符,我们就要用小括号进行分组。

var reg = /^(bye){2}$/;
console.log(reg.test("byebye"));
console.log(reg.test("bbyyee"));

或操作符

可以使用竖线 | 字符表示或者的关系
/a|bcd/ 匹配a或bcd字符。
/(ab)+|(cd)+/匹配出现一次或多次的ab或者cd

//或操作符 | 
var reg = /^a|bcd$/;    //匹配时,要么匹配以a开头的,要么匹配以 bcd 结尾的
console.log(reg.test("cbcde"));
console.log(reg.test("acbcde"));
console.log(reg.test("abcd"));
// 如果想在正则中,在两个规则之间只能选其中一个,不能包含其他的开头结尾,需要去将或运算放到分组里
var reg = /^(ab|cd)$/;
console.log(reg.test("abcd"));// 输出false
console.log(reg.test("ab"));// 输出true
console.log(reg.test("cd"));// 输出true

分组的反向引用

// 正则中通过分组匹配到的字符串,会被进行编号,从 1 开始
// 在正则内部可以通过 $1 方式,去对字符串进行反向引用
console.log(/^([a-z]{3})\1$/.test("byebye"));
console.log(/^([a-z]{3})\1$/.test("byelie"));
// 正则表达式以外通过 $1 ,进行字符串的引用
var str = "123*456".replace(/^(\d{3})\*(\d{3})$/,"$2*$1");
// 第二个参数可以是一个函数
var str = "123*456".replace(/^(\d{3})\*(\d{3})$/,function (match,$1,$2) {
    return $1 * 3 + "/" + $2 * 2;
});
console.log(str);

中文匹配

匹配中文:[\u4e00-\u9fa5]

// 匹配中文字符
var reg = /^[a-z\u4e00-\u9fa5]+$/;
console.log(reg.test("只有中文的文字内容"));
console.log(reg.test("只有中文的文 字内容"));
console.log(reg.test("只有中文的文a字内容"));