本文
- 简单介绍
- 正则实例分析
- 正则 JS高程三内容 概述(复习)
- 再来看一些正则实例
一.简单介绍
正则总是给我一种 四两拨千斤的感觉。
ECMAScript 通过 RegExp 来支持正则表达式。
const expression = / pattern / flags;
- 模式就是我们的正则表达式。
- 每个正则可以带有 1 或者 多 个标志
- g:global,全局标志
- i:ignore,表示不区分大小写
- m:multiline,表示到达一行文本的末尾,还会继续查找下一行与文本匹配的。
二. 正则实例分析
概念是死的,如果我们只是去背概念,那我们每一次学习 都会跟 考古 似的。所以我们学习正则的方式应该是 多去写 正则相关的题目。
来看看我所接触过的正则吧~
let array = ' 桃李春风 一杯酒,江湖夜雨十 年灯 ';
1. JS去除空字符串(对比一下,不用正则和用正则?)
法一(最土的办法==) (非正则办法) - 去除 所有的 空格
const way1 = (str) => {
let res = [];
for (let i = 0; i < str.length; i++) {
if (str[i] !== ' ') {
res.push(str[i]);
}
}
return res.join('');
}
法二(稍微先进一点,石器时代) - 利用 数组方法 filter
const way2 = (str) => {
return str.split('').filter(item => item !== ' ').join('');
}
console.log(way2(array));
法三(现代)
const way2 = (str) => {
return str.replace(/s/g, '');
}
现代人有现代人的问题,我们把小问题升级。 去除开头和结尾的空格。
法一(铁器时代)
const trim = (str) => {
let pre,next;
for (let i = 0; i < str.length; i++) {
if (str[i] !== " ") {
pre = i;
break;
}
}
for (let i = str.length - 1; i >= 0; i--) {
if (str[i] !== " ") {
console.log(i);
next = i;
break;
}
}
str = str.substring(pre, next+1); // (start, end] 所以要 +1
}
trim(array);
法二(正则)- 一旦局势复杂起来,正则的作用就更加明显了。
const trim = (str) => {
return str.replace(/^(s*)|(s*)$/g, "");
}
console.log(trim(array));
法三. ES5 基本包装类型 String 自带的方法 trim/trimLeft/trimRight
其实,ES5 早已给了我们方法,只需要调用就可以了
。完全不需要我们去实现 函数 ==
console.log(array.trim());
三. 正则高程三
A.正则有几个没有什么卵用的属性
- global
- ignoreCase
- lastIndex (这个还挺有用,特别是exec的时候)
- multiple
- source
他们是干什么的呢?简单来说,就是返回 正则一些的 属性,就跟 length
差不多吧。
问题在于,正则本身的样子已经很清楚了。就像,我是个男的,你却对我问 你是不是男的??
,考虑到汉语的博大精深,这里只考虑 符合理性和逻辑 的用法。我是男的难道 你眼睛 看不出来???
所以说这些属性没有什么卵用嘛。不过还是拿来用用试试?不用你怎么知道我有多菜??
const reg = /chen{8}/gi;
console.log(reg.global); // true, 废话,表达式里写了 g
console.log(reg.ignoreCase); // true, 废话,表达式里写了 i
console.log(reg.multiline); // false,废话,表达式没写 m
console.log(reg.lastIndex); // 0 ,现在查到 0,注意,这个是可以遗传给下一次匹配的
console.log(reg.source); // chen{8}
B. 正则对象的实例方法
1. exec
使用方法: reg.exec(str)
返回:若有匹配项,则返回一个数组(有两个额外的属性index
和input
);若无匹配则返回null
- index - 匹配项在字符串中的位置
- input - 应用正则表达式的字符串
const reg = /chen/gi;
let str = "chen323";
console.log(reg.exec(str)); // ['chen', index: 0, input: 'chen323']
而返回的数组中。
- 第一项是与整个模式匹配的字符串。
- 第二项是与模式中的捕获组匹配的字符串。
- 第三项...捕获组的捕获组...
...
我想到了一首歌:
如果你愿意一层一层一层的剥开我的心
你会发现你会讶异
你是我最压抑
最深处的秘密
var text = 'read write and dream';
var pattern = /read( write and( dream))/gi;
var matches = pattern.exec(text);
console.log(matches[0]); // read write and dream
console.log(matches[1]); // write and dream
console.log(matches[2]); // dream
这里还要注意一件事情。连续地使用 exec 和 flags-g 的关系
1.如果使用 /g
var text = "678";
var reg = /(d)/g;
for (let i = 0; i < 3; i++) {
console.log(reg.exec(text));
console.log(reg.lastIndex);
}
// ['6', '6', index: 0, input: '678']
// 1
// ['7', '7', index: 1, input: '677']
// 2
// ['8', '8', index: 2, input: '678']
// 3
2.如果不使用 /g
var text = "678";
var reg = /(d)/;
for (let i = 0; i < 3; i++) {
console.log(reg.exec(text));
console.log(reg.lastIndex); // 永远都是 0
}
这样的话,三次都会返回 ['6', '6', index: 0, input: '678']
另外,reg.test
方法的/g
模式也会影响到 reg.exec
的lastIndex
,上面的循环中使用reg.test
也是一样的。
2. test方法
若是匹配返回 true,若是无匹配,返回 false,常用于 if 判断
var text = /000-00-000/;
var pattern = /d{3}-d{2}-d{3}/;
if (pattern.test(text)) { // true
console.log("成功匹配"); // 成功匹配
}
C. 正则构造函数属性
- input($_)
- lastMatch($&)
- lastParen
- leftContext
- multiline
- rightContext
这里待更。(时间原因)
除此之外,还有多达 9个 存储获取组 的构造函数属性。在我们调用exec
和test
的时候,它们会被 自动填充。
const r = /^(d{4})-(d{1,2})-(d{1,2})$/;
const x = r.exec('1992-32-23');
console.log(RegExp.$1, RegExp.$2); // 1992 32
MDN文档
var re = /(w+)s(w+)/;
var str = 'John Smith';
str.replace(re, '$2, $1'); // "Smith, John"
RegExp.$1; // "John"
RegExp.$2; // "Smith"
四.还是一些实例。常用常新
// todo