3

JS正则表达式知识点归纳

 3 years ago
source link: https://segmentfault.com/a/1190000040615800
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

JS正则表达式知识点归纳

发布于 9 月 1 日

什么是正则表达式?

正则表达式是由一个字符序列形成的搜索模式。当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。正则表达式可以是一个简单的字符,或一个更复杂的模式。正则表达式可用于所有文本搜索和文本替换的操作。

正则表达式创建

  1. 字面量(直接量)
// 在一对反斜线中写正则表达式内容,如/abc/
// 正则表达式里面不需要加引号 不管是数字型还是字符串型
var pattern=/正则表达式/修饰符;
var pattern=/qwer/igm;
//构造正则表达式的实例,如new RexExp('abc')
//内部传入的参数为字符串/字符串的变量
var reg =new RegExp("正则表达式","修饰符")
var reg =new RegExp("hello","g");

字符的分类

  字母、数字、下划线、汉字、没有特殊含义的符号(,;!@等)

  实际上不是特殊字符的字符都是普通字符

  \:将特殊字符转义成普通字符

模式修饰符

  i:ignoreCase,匹配时忽视大小写

  m:multiline,多行匹配

  g:global,全局匹配

  字面量创建正则时,模式修饰符写在一对反斜线后

正则表达式实例方法

  1. exec---->>可用来匹配字符串中符合正则表达式的字符串

如果匹配到,返回值是一个result数组:[匹配的内容,index: 在str中匹配的起始位置,input: 参数字符串,groups: undefined],r如果匹配不到则返回null

var str = 'hello world hello';
var reg1 = /hello/;
var reg2 = /hello/g;  //g表示全局匹配,也就是会匹配到str中所有满足正则表达式条件的字段
var reg3 = /exe/g;
console.log(reg1.exec(str)); //[ 'hello', index: 0, input: 'hello world hello', groups: undefined ]
console.log(reg2.exec(str)); //[ 'hello', index: 0, input: 'hello world hello', groups: undefined ]
console.log(reg3.exec(str)); // null     //str中并不存在exe字段,所以输出null

// 如果是全局模式的正则验证 还可以使用循环进行输出
var reg = /hello/g;
var str = 'hello world hello hello good';
while(true)
    var result = reg.exec(str);
    if(!result){
        break;
    }
    console.log(result[0],result["index"],reg.lastIndex);  //hello 18 23
}

需要注意的地方就是

1)如果正则表达式中有修饰符"g",这时,在正则表达式的实例reg中会维护lastIndex属性,记录下一次开始的位置,当第二次执行exec的时候,从lastIndex开始检索。
2)如果正则表达式中没有修饰符"g",不会维护lastIndex属性,每次执行从开始位置检索

2.test ---->> 用来测试待检测的字符串中是否有可以匹配到正则表达式的字符串,如果有返回true,否则返回false

var str = 'hello world';
var reg1 = /world/;
var reg2 = /Regex/;
console.log(reg1.test(str)); //返回true
console.log(reg2.test(str)); //返回false

其实我比较喜欢把字符串str放在test()更好看(直观校对)哈~~~

var reg1 = /world/;
var reg2 = /Regex/;
console.log(reg1.test(hello world)); //返回true
console.log(reg2.test(hello world)); //返回false

//由结果可知
//字符串中是否有可以匹配到正则表达式的字符串world,所以返回true

3.toString/toLocaleString --->> 把正则表达式的内容转化成字面量形式字符串/有本地特色的字符串(JS中没效果)

var reg1 = /hello/;
console.log(reg1.toString()); //   /hello/    string
console.log(reg1.toLocaleString()); //   /hello/   string

4.valueOf ------>> 返回一个 Number 对象的基本数字值

它的作用是返回正则表达式本身

var reg1 = /hello/;
console.log(reg1.valueOf());  //    /hello/      返回正则表达式本身

正则表达式实例属性

  1. lastIndex
    在菜鸟教程的解析为astIndex 属性用于规定下次匹配的起始位置,该属性只有设置标志 g 才能使用。

所以,当没设置全局匹配时,该属性值始终为0

设置了全局匹配时,每执行一次exec/test来匹配,latIndex就会移向匹配到的字符串的下一个位置,当指向的位置后没有可以再次匹配的字符串时,下一次执行exec返回null,test执行返回false,然后lastIndex归零,从字符串的开头重新匹配一轮

可以理解成,每次正则查找的起点就是lastIndex

简而言之,全局匹配字符 g 对lastindex起到维护的作用,没有 g ,lastindex就没有作用

var reg =new RegExp('hello')
var reg1 = /hello/g;
var str = 'hello hello hello';  //字符串最后一个数的后面存在一个空字符'hello hello hello""'

console.log('正则表达式构造函数');
console.log(reg.lastIndex); //0
console.log(reg.exec(str)); //返回第一个hello
console.log(reg.lastIndex); //0


console.log('正则表达式字面量');
console.log(reg1.lastIndex); //0
console.log(reg1.exec(str)); //[ 'hello', index: 0, input: 'hello hello hello', groups: undefined ]  第一个hello
//每执行一次exec/test来匹配,latIndex就会移向匹配到的字符串的下一个位置  所以当前lastIndex正好指向空格
console.log(reg1.lastIndex); //5

console.log(reg1.lastIndex); //5
console.log(reg1.exec(str)); //返回第二个hello   [ 'hello', index: 6, input: 'hello hello hello', groups: undefined ]
//每执行一次exec/test来匹配,latIndex就会移向匹配到的字符串的下一个位置  所以当前lastIndex正好指向空格
console.log(reg1.lastIndex); //11

console.log(reg1.lastIndex); //11
console.log(reg1.exec(str)); //返回第三个hello   [ 'hello', index: 12, input: 'hello hello hello', groups: undefined ]
//每执行一次exec/test来匹配,latIndex就会移向匹配到的字符串的下一个位置  所以当前lastIndex正好指向空格
console.log(reg1.lastIndex); //17    //因为字符串最后一个数的后面存在一个空字符'hello hello hello""'

console.log(reg1.exec(str));  //null

// 当指向的位置后没有可以再次匹配的字符串时,重新开始找
console.log(reg1.lastIndex); //0
console.log(reg1.exec(str));  //返回第一个hello   [ 'hello', index: 0, input: 'hello hello hello', groups: undefined ]

2.ignoreCase、global、multiline------>>判断正则表达式中是否有忽略大小写、全局匹配、多行匹配三个模式修饰符

var reg1 = /hello/igm;
console.log(reg1.ignoreCase); //true   忽略大小写
console.log(reg1.global); //true  全局匹配
console.log(reg1.multiline);  //true   多行匹配

3.source --->> 返回字面量形式的正则表达式(类似于toString)

var reg1 = /hello/igm;
console.log(reg1.source);  //hello   返回正则表达式本身

正则表达式语法-元字符

正则表达式中的所有字母和数字都是按照字面含义进行匹配的,Javascript正则表达式语法也支持非字母的字符匹配,这些字符需要通过反斜线\作为前缀进行转义。

  1. 直接量字符

  2. 字符集合
    一个字符集合,也叫字符组。匹配集合中的任意一个字符。你可以使用连字符‘-’指定一个范围

方括号用于查找某个范围内的字符:

[abc] 查找方括号之间的任何字符

var str = 'abc qwe abd'
var reg1 = /[abc]/;// 只要包含有a 或者 包含有b 或者包含有c 都返回为true
console.log(reg1.test(str)); //true

[0-9] 查找任何从0至9的数字

var str = 'abc qwe abd1'
var reg1 = /[0-9]/igm;
console.log(reg1.test(str)); //true

一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符。

注意^写在[]里面是补充字符集

//反义字符组
//它匹配任意不在括号内的字符。你也可以通过使用连字符 '-' 指定一个范围内的字符。
var str = 'abc qwe abd1,2'
console.log(str);
var reg1 = /[^abc]/igm; //除了abc,可取其他任意字符
console.log(reg1.exec(str)); 
//[ 'q', index: 4, input: 'abc qwe abd1,2', groups: undefined ]
console.log(reg1.test(str)); //true //
  • ^ 匹配输入开始。表示匹配行首的文本(以谁开始)。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符后的开始处。

// 以 ^ 开始
// 必须是以hel开头的字符串才会满足
var reg = /^[hel]/;
console.log(reg.exec(hello world hello Regexp));   // [ 'h', index: 0, input: 'hello world hello Regexp', groups: undefined ]
console.log(reg.test(hello world hello Regexp)); //true
console.log(reg.test('aabcd')); // false
  • $ 匹配输入结尾。表示匹配行尾的文本(以谁结束)。如果多行(multiline)标志被设为 true,该字符也会匹配一个断行(line break)符的前的结尾处。
//  以 $ 结束
// 必须是以exp结尾的字符串才会满足
var reg1 = /[exp]$/;
console.log(reg1.exec(hello world hello Regexp));
// [
//      'p',
//      index: 23,
//      input: 'hello world hello Regexp',
//      groups: undefined
//    ]
console.log(reg1.test(hello world hello Regexp));  //true
console.log(reg.test('aabcd')); // false
  • 如果 ^和 $ 在一起,表示必须是精确匹配。
// 如果 ^和 $ 在一起,表示必须是精确匹配
var reg2 = /^hello$/;
console.log(reg2.test('hello'));  //true
console.log(reg2.test('helloeeee'));  //false

4.字符集合与"^"和"$"一起使用

// 字符集合与"^"和"$"一起使用

// 三选一 只有是a 或者是 b  或者是c 这三个字母才返回 true
var rg1 = /^[abc]$/;     //单个匹配 
console.log(rg1.test('aa'));//false
console.log(rg1.test('a'));//true
console.log(rg1.test('b'));//true
console.log(rg1.test('c'));//true
console.log(rg1.test('abc'));//false

//26个英文字母任何一个字母返回 true  - 表示的是a 到z 的范围  
var reg = /^[a-z]$/
console.log(reg.test('a'));//true
console.log(reg.test('z'));//true
console.log(reg.test('A'));//false


//字符组合
// 26个英文字母(大写和小写都可以)任何一个字母返回 true
var reg1 = /^[a-zA-Z0-9]$/;

//取反 方括号内部加上 ^ 表示取反,只要包含方括号内的字符,都返回 false 。
var reg2 = /^[^a-zA-Z0-9]$/;
console.log(reg2.test('a'));//false
console.log(reg2.test('B'));//false
console.log(reg2.test(8));//false
console.log(reg2.test('!'));//true
console.log(reg2.test('?'),'其他字符'); //true
console.log(reg2.test(':'),'其他字符'); //true
console.log(reg2.test('='),'其他字符'); //true

\b 匹配一个零宽单词边界(zero-width word boundary),表示一个单词(而非字符)边界,也就是单词和空格之间的位置,或者字符(\w)与字符串开头或者结尾之间的位置。

\B 匹配一个零宽非单词边界(zero-width non-word boundary),与"\b"相反。

我觉得这个讲的非常好懂,我不懂怎么陈述,这得自个悟我觉得

//
var str = 'this is a former browser';
// \b   匹配一个零宽单词边界,表示一个单词(而非字符)边界,
// 也就是单词和空格之间的位置,或者字符(\w)与字符串开头或者结尾之间的位置。

var text = "this is a former browser!";
console.log(text.match(/\b.s\/g)); //is  //这个is是单个的is


// \B  匹配一个零宽非单词边界,与"\b"相反
var text = "this is a former browser!";
console.log(text.match(/\B.s/g)); // is ws   //这个is是this里面的is

  1. 字符类
    将直接量字符单独放进方括号内就组成了字符类,一个字符类可以匹配它所包含的任意字符。例如:/[abc]/ 就和字母"a"、"b"、"c"中的任意一个都匹配。"^"符号用来定义否定字符类,例如: 匹配的是"a"、"b"、"c"之外的所有字符。字符类可以使用连字符来表示字符范围,例如:/[a-z]/,要匹配拉丁字母表中任何字母和数字,[a-zA-Z0-9]

老师推荐的记忆方法---->>联想记忆法

结合英文原意记忆:
d ==> digit(数字)
s ==> space(空白)
w ==> word(单词)

接下来,我们进行逐个剖析 总而言之,小写和大写的字符类是互为反义的

  • "." 除换行符\n和回车符之外的任何单个字符
//"." 除换行符\n之外的任何单个字符
var str = '\ngood World Hello\r JavaScript';

var reg1 = /./g;
console.log(reg1.exec(str));
// [
//     'g',
//     index: 1,
//     input: '\ngood World Hello\r JavaScript',
//     groups: undefinedl;
//   ]
console.log(reg1.test('\ngood World Hello JavaScript'));  //true  字符串中有满足条件的就返回true
console.log(reg1.test('\n'));  //false
console.log(reg1.test('\r'));  //false

  • \d 匹配一个数字字符,等效于[0-9]
//  \d 匹配一个数字字符,等效于[0-9]
// 以数字开头
var str = '123Hello World Hello JavaScript';
var str1 = 'Hello World Hello 123JavaScript';

var reg4 = /^\d/;
console.log(reg4.exec(str)); 
console.log(reg4.test(str),'数字开头时');  //true
console.log(reg4.test(str1));  //false
  • HN2JAX{VNZKFH)5}~6ZV{P1.png
// \D 等效于[^0-9]
// 不以数字开头
var str = 'Hello World Hello 123JavaScript';
var str1 = '123Hello World Hello 123JavaScript';
console.log(str);
var reg1 = /^\D/;
console.log(reg1.exec(str));
console.log(reg1.test(str),'不以数字开头');  //true 不以数字开头
console.log(reg1.test(str1),'以数字开头'); //false 不以数字开头
  • \s 匹配任何Unicode空白字符,包括空格、制表符、换页符等,等效于[\f\t\n\r]
// \s 匹配任何Unicode空白字符,包括空格、制表符、换页符等,等效于[\f\t\n\r]
// 以空白字符开头
var str = ' Hello World Hello 123JavaScript';
var reg1 = /^\s/;
console.log(reg1.exec(str),'以空白字符开头'); 
// [
//     ' ',
//     index: 0,
//     input: ' Hello World Hello 123JavaScript',      
//     groups: undefined
//   ] 
console.log(reg1.test(str),'以空白字符开头');  //true
  • 941N4$D{0K{T9Y531}{F(Z8.png
//   \S 等效于**[^\f\t\n\r]
// 不以空白字符开头
var str = 'Hello World Hello 123JavaScript';
 
var reg1 = /^\S/;
console.log(reg1.exec(str)); 
// [
//     'H',
//     index: 0,
//     input: 'Hello World Hello 123JavaScript',       
//     groups: undefined
//   ]
console.log(reg1.test(str));  //true
  • \w 匹配包括下划线的任何单个字符,包括A~Z,a~z,0~9和下划线"",等效于[a-zA-Z0-9_]
// \w 匹配包括下划线的任何单个字符,包括A~Z,a~z,0~9和下划线"",等效于[a-zA-Z0-9_]/
var str = 'Hello World Hello JavaScript';
// \w -> [a-zA-Z0-9_]
var reg1 = /^\w/;
console.log(reg1.exec(str),'www'); 
// [
//     'H',
//     index: 0,
//     input: 'Hello World Hello JavaScript',
//     groups: undefined
//   ]
console.log(reg1.test(str));  //true
console.log(reg1.test('!Hello World Hello JavaScript'));  //false
  • \W 匹配不包括下划线的任何单个字符,包括A~Z,a~z,0~9和下划线"",就是\w的反义
// \W -> [^a-zA-Z0-9_]
var str = '!Hello World Hello JavaScript';
var reg2 = /^\W/;
console.log(reg2.exec(str));
// [
//     '!',
//     index: 0,
//     input: '!Hello World Hello JavaScript',
//     groups: undefined
//   ]
console.log(reg2.test(str)); //true
字符含义*>=0次+≥1 次?0或1次{n}n 次{n,}≥n 次{n,m}n到m 次
  • X* 匹配前面的模式 x ---> 0 或多次。等价于{0,}
// * 允许出现0次或多次
var reg = new RegExp(/^a*$/);
console.log(reg.test("a")); // true
console.log(reg.test("aaaaaaaaaaaaa")); // true
console.log(reg.test("")); // true
  • X+ 匹配前面的模式 x ---> 1 或多次。等价于 {1,}。
// + 允许出现1次或多次
var reg2 = new RegExp(/^a+$/);
console.log(reg2.test("a")); // true
console.log(reg2.test("")); // false
  • X? 匹配前面的模式 x ---> 0 或 1 次。等价于{0,1}
// ? 只允许a出现1次或0次
var reg3 = new RegExp(/^a?$/);
console.log(reg3.test("a")); // true
console.log(reg3.test("")); // true
console.log(reg3.test("aaa")); // false
  • X{n} n为非负整数。前面的模式 x 重复出现 n 次时匹配
// {3} 允许重复3次
var reg4 = new RegExp(/^a{3}$/);
console.log(reg4.test("a")); // false
console.log(reg4.test("")); // false
console.log(reg4.test("aaa")); // true,
console.log(reg4.test("aaaa")); // false
  • X{n,} n为非负整数。前面的模式 x 重复出现至少 n 次时匹配。
// {3,} 允许重复出现3次或3次以上多次
var reg5 = new RegExp(/^a{3,}$/);
console.log(reg5.test("a")); // false
console.log(reg5.test("")); // false
console.log(reg5.test("aaa")); // true
console.log(reg5.test("aaaa")); // true
  • X{n,m} n和m为非负整数。前面的模式 x 重复出现至少 n 次,至多 m 次时匹配。
// {3,6} 允许重复出现3次-6次之间,也就是>=3且<=6
var reg6 = new RegExp(/^a{3,6}$/);
console.log(reg6.test("a")); // false
console.log(reg6.test("aaaa")); // true
console.log(reg6.test("aaaaaa")); // true
console.log(reg6.test("aaaaaaa")); // false

案例:用正则表达式匹配11位有效手机号、QQ号、身份证号、密码验证

1.匹配QQ号

//匹配QQ号  用到精准匹配^ $
//不能以数字0开头 只能由数字组成 长度为5-11位
var regQQ = /^[1-9]\d{4,10}$/;  //因为^[1-9] 已经占了一位,所以后面的数的长度范围就为{4,10}
console.log(regQQ.test('12311111224')); //true
console.log(regQQ.test('02311111224')); //false
console.log(regQQ.test('0588247')); //false

2.匹配身份证号

//身份证号码是18位的
// 不能以数字0开头,只能由数字组成,最后一位可能是x,X,数字
var reg = /^[1-9]\d{16}(x|X|\d)$/;   //可用到选择分组我觉得 
//又或者写成var reg = /^[1-9]\d{16}[xX\d]$/; 也可   
console.log(reg.test('450521196767676776')); //true
console.log(reg.test('45052119991006692X')); //true
console.log(reg.test('45052119991006692x')); //true
console.log(reg.test('0450521199910022227')); //false

3.验证是否为11位有效手机号码?

  • 以1为开头
  • 第二位为3,4,5,7,8中的任意一位
  • 最后以0-9的9个整数结尾
// 以1为开头
//第二位为3,4,5,7,8中的任意一位
// 最后以0-9的9个整数结尾
var myreg = /^[1][3,4,5,7,9][0-9]{9}$/;  //  \d 等效于 [0-9]
console.log(myreg.test('17878273092'));   //true

4.密码验证
匹配密码,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位

//匹配密码,必须包含大写,小写和数字,和特殊字符 
 (!,@,#,%,&),且大于6位

var pattern = /(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!|@|%|&])[A-Za-z0-9!@%&]{6,}/
console.log(pattern.test('Ac3!56'),'password');    //true

重复方式(贪婪模式和非贪婪模式)

  • 最直接的理解就是贪婪模式是尽可能多的匹配,非贪婪模式是尽可能少的匹配

1)贪婪模式:尽可能多的匹配(首先取最多可匹配的数量为一组进行匹配),当匹配剩余的字符串,还会继续尝试新的匹配,直到匹配不到为止,为默认模式

// 对字符串"123456789",匹配其中的数字3-6次:\d{3,6},先匹配数字出现6次的字符串(123456),
//然后再从剩余字符串(789)中匹配出现数字3次的情况,剩余字符若没有出现数字3次则停止匹配.
var str = "123456789";
var reg = /\d{3,6}/g;
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678', groups: undefined ]
console.log(reg.exec(str)); // [ '789', index: 6, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // null

2)非贪婪模式:尽可能少的匹配(每次取最少匹配的数量为一组进行匹配),直到匹配不到为止
使用方法:在量词后加上

// 对字符串"123456789",匹配其中的数字3-6次:\d{3,6},先匹配数字出现3次的字符串(123456),
//然后再从剩余字符串(456789)中匹配出现数字3次的情况,剩余字符若没有出现数字3次则停止匹配.
var str = "123456789";
var reg = /\d{3,6}?/g;
console.log(reg.exec(str)); //[ '123', index: 0, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // [ '456', index: 3, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // [ '789', index: 6, input: '123456789', groups: undefined ]

选择,分组,引用

  • 选择
    字符"|"用于分隔供选择的字符,选择项的尝试匹配次序是从左到右,知道发现了匹配项,如果左边的选择项匹配,就忽略右边的匹配项,即使它可以产生更好的匹配。
var reg = /html|css|js/
console.log(reg.exec('qweqwehtmlcss')); // html
  • 分组
    下面的正则表达式可以匹配'briupbriupbriup'
这里有圆括号包裹的一个小整体成为分组。
var reg = /(briup){3}/;

候选:一个分组中,可以有多个候选表达式,用 | 分隔:

var reg = /I Like (basketball|football|table tennis)/
console.log(reg.test('I Like basketball')); //true
console.log(reg.test('I Like football')); //true
console.log(reg.test('I Like table tennis')); //true

捕获与引用:被正则表达式匹配(捕获)到的字符串会被暂存起来。其中,由分组捕获的串会从1开始编号,于是我们可以引用这些串:

var reg = /(\d{4})-(\d{2})-(\d{2})/

var date = '2021-08-29'

reg.test(date)
// 捕获之前要先test/exec
//$1引用了第一个被捕获的串,$2是第二个,依次类推。
console.log(RegExp.$1); //2021
console.log(RegExp.$2); //08
console.log(RegExp.$3); //29

嵌套分组的捕获
如果碰到类似/((apple) is (a (fruit)))/的嵌套分组,捕获的顺序是什么?

规则是以左括号出现的顺序进行捕获,从左到右,遇到左括号就捕获

var reg = /((apple) is (a (fruit)))/
var str = "apple is a fruit"
reg.test(str) // true
RegExp.$1 // apple is a fruit
RegExp.$2 // apple
RegExp.$3 // a fruit
RegExp.$4 // fruit

正则表达式里也能进行引用,这称为反向引用:

//\1引用了第一个被分组所捕获的串,换言之,表达式是动态决定的。

var reg = /(\w{3}) is \1/   //就是\w{3}和\1对等时才为true
console.log(reg.test('kid is kid')); // true
console.log(reg.test('dik is dik')); // true
console.log(reg.test('kid is dik')); // false
console.log(reg.test('dik is kid')); // false

注意如果编号越界了,则会被当成普通的表达式:

var reg = /(\w{3}) is \6/;   //编号越界了
reg.test( 'kid is kid' ); // false
reg.test( 'kid is \6' );  // true

String对正则表达式的支持

  • search ---->> 查找字符串中是否有匹配正则的字符串,返回索引值
var str = 'hello world hello'
var regSea = /world/;
var reg2 = /hello/g;

console.log(regSea.exec(str));   //[ 'hello', index: 0, input: 'hello world hello', groups: undefined ]

console.log(str.search(regSea));  //6   //匹配到返回索引值
console.log(str.search(reg2)); //0
  • match ---->> 匹配字符串中符合正则表达式的字符串,返回该字符串的一个数组

匹配字符串中符合正则表达式的字符串,并返回该字符串的一个数组,其中包括字符串内容位置

如果正则设置全局匹配,则一次性返回所有符合正则表达式的字符串数组

如果其中添加了分组,返回符合要求的字符串以及分组的一个数组,但如果同时开启全局匹配则不会在数组中添加分组内容

//match
// 匹配字符串中符合正则表达式的字符串,并返回该字符串的一个**数组**,其中包括字符串**内容**、**位置**
// 如果正则设置全局匹配,则**一次性返回所有**符合正则表达式的字符串数组
// 如果其中添加了分组,返回符合要求的字符串以及**分组**的一个数组,但如果同时开启全局匹配则**不会在数组中添加
var str = 'hello world hello';
var reg1 = /hello/;
var reg2 = /hello/g;
var reg3 = /(he)llo/;
var reg4 = /(he)llo/g;
// 匹配字符串中符合正则表达式的字符串,并返回该字符串的一个数组,其中包括字符串内容、位置
console.log(str.match(reg1));  // [ 'hello', index: 0, input: 'hello world hello', groups: undefined ]

// 如果正则设置全局匹配,则一次性返回所有符合正则表达式的字符串数组
console.log(str.match(reg2));   // [ 'hello', 'hello' ]

// 如果其中添加了分组,返回符合要求的字符串以及分组的一个数组
console.log(str.match(reg3));
// [
//   'hello',
//   'he',
//   index: 0,
//   input: 'hello world hello',
//   groups: undefined
// ]


// 如果同时开启全局匹配则不会在数组中添加分组内容
console.log(str.match(reg4));  // [ 'hello', 'hello' ]

  • split ---->>以某种形式分割字符串,返回数组
// 以某种形式分割字符串 split()
var str = "terry134briup156lisi12zhangsan";
// 当数字出现一次或多次时
var reg = /\d+/;  //匹配到数字时就切割开来
var result = str.split(reg);
console.log(result); // [ 'terry', 'briup', 'lisi', 'zhangsan' ]


例如:
// 以某种形式分割字符串 split()
var str = "world";
 
var reg = /\s?/; //以Unicode空格符形式切割  其实字符串的每两个单字符之间都默认存在一个空字符 所以才会切割成功
var result = str.split(reg);
console.log(result); //  [ 'w', 'o', 'r', 'l', 'd' ]
  • replace --->> 满足正则表达式条件的内容将被替换
//replace  满足正则表达式条件的内容将被替换
var str  = 'hello world good place';
var reg = /\bhello\b/;
console.log(str.replace(reg,'go'));  //go world good place

前瞻表达式

在正则表达式当中有个东西叫做前瞻,有的管它叫零宽断言:

表达式名称描述(?=exp)正向前瞻匹配后面满足表达式exp的位置(?!exp)负向前瞻匹配后面不满足表达式exp的位置
var str = 'Hello, Hi, I am Hilary.';
var reg = /H(?=i)/g;   //从左到右,前一个字符是H,后一个字符是i,那么这个H就会被匹配到,并被T替换
var newStr = str.replace(reg, "T");
console.log(newStr);  // Hello, Ti, I am Tilary.

再举个栗子:

var str='a2*34v8';
 //从左到右,每两个字符进行校对,\w相当于[a-zA-Z0-9_  ],
//前一个字符符合\w,后一个字符符合[0-9],那么前一个字符就被替换成X
var result=str.replace(/\w(?=\d)/g,'X');
console.log(result);   //X2*X4X8

关于前瞻有个小故事。。。

在这个DEMO中我们可以看出正向前瞻的作用,同样是字符"H",但是只匹配"H"后面紧跟"i"的"H"。就相当于有一家公司reg,这时候有多名"H"人员前来应聘,但是reg公司提出了一个硬条件是必须掌握"i"这项技能,所以"Hello"就自然的被淘汰掉了。

var str = 'Hello, Hi, I am Hilary.';
var reg = /H(?!i)/g;    //跟正向前瞻相反,负向前瞻则是从左到右,前一个字符是H,后一个字符不是i时,那么这个H就会被匹配到,并被T替换
var newStr = str.replace(reg, "T");
console.log(newStr);//Tello, Hi, I am Hilary.
var str='a2*34v8';
var result=str.replace(/\w(?!\d)/g,'X');//[^0-9a-zA-z_ ]
console.log(result)    //aX*3XvX

继续讲故事。。。

在这个DEMO中,我们把之前的正向前瞻换成了负向前瞻。这个正则的意思就是,匹配"H",且后面不能跟着一个"i"。这时候"Hello"就可以成功的应聘了,因为reg公司修改了他们的招聘条件,他们说"i"这门技术会有损公司的企业文化,所以我们不要了。

终于完事了。。。。。。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK