难以启齿的正则

JS正则表达式

既然是正则那就先从字符串操作开始

search(‘xxx’)

  • 字符串操作返回查找字符串的位置
  • 没找到返回 -1
1
2
3
4
5
6
7
8
9
var str = 'abcdef';

console.log(str.search('a')) // 0
console.log(str.search('b')) // 1
console.log(str.search('c')) // 2
console.log(str.search('d')) // 3
console.log(str.search('e')) // 4

console.log(str.search('x')) // -1

substring()

口诀「包头不包尾」(左闭右开)

获取子字符串

1
2
3
4
5
var str = 'abcdef';
console.log(str.substring(2,5)) //cde
console.log(str.substring(1)) // bcdef
console.log(str.substring(6)) // ''空字符
console.log(str.substing(-1)) //abcdef

charAt()

获取某个字符

1
2
var str = 'abcdef';
console.log(str.charAt(3)) //d

split()

分割字符串,获取数组

1
2
3
var str = '13-14-aaa-xxx';
var arr = str.split('-');
console.log(arr) // [13,14,'aaa','xxx']

为什么要学正则

需求查找字符串里的数字

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var str = '12 fff 87 er334 233 -=-=fa80';
var arr = [];
var tmp = '';

for(var i=0;i<str.length;i++){
if(str.charAt(i) >= '0' && str.charAt(i) <= '9'){
tmp+=str.charAt(i);
}else{
if(tmp){
arr.push(tmp);
tmp = '';
}
}
}
console.log(arr) //['12','87','334','80']

if 正则

1
2
3
4
5
6
var str = '12 fff 87 er334 233 -=-=fa80';
var arr = [];

arr = str.match(/\d+/g)

console.log(arr) //['12','87','334','80']

什么是正则

一串英文、数字 @ - 一串英文、各种文 「计算机」是看不懂的

计算机只懂 0/1 、逻辑、程序 —->规则、模式

  • 强大的字符串匹配工具
  • 一种正常人类很难懂得文字
  • RegExp对象

正则就是干

  • 两种风格迥异的使用方式
需求1 看第一个例子查找字母 ‘a’
1
2
3
4
5
// js风格
var reg = new RegExp('a');
var str = 'abcdef';

console.log(str.search(reg)); // 0

另一种风格

1
2
3
4
// perl风格
var reg = /a/;
var str = 'abcdef';
console.log(str.search(reg)); // 0
需求2 查找忽略大小写的字母 ‘b’
忽略大小写之「i」(ignore)
1
2
3
4
5
// js风格
var reg = new RegExp('b','i');
var str = 'aBcdef';

console.log(str.search(reg)); // 0

另一种风格

1
2
3
4
// perl风格
var reg = /a/i;
var str = 'Abcdef';
console.log(str.search(reg)); // 0
search 和 match 的区别

search是查找匹配规则的字符(只找一次,找到匹配规则的第一个索引返回)

match 是返回所有匹配规则的东西都取出来

1
2
3
4
5
var reg = /\d/;
var str = 'asdf 34 657 cs33';
console.log(str.search(reg)) //5
alert(str.match(reg)) // 3
console.log(str.match(reg)) // ["3", index: 5, input: "asdf 34 657 cs33", groups: undefined]

match返回3是因为 计算机很蠢,你只告诉它找数字,没告诉它找几个

但是,正则天生懒惰想变勤奋你得加「g」

「g」global

那你就给我勤奋一点!

1
2
3
var reg = /\d/g;
var str = 'asdf 34 657 cs33';
console.log(str.match(reg)) // ["3", "4", "6", "5", "7", "3", "3"]

怎么出来的都是个位的数字?

因为你只告诉计算机取一个数字

量词(个数)
1
2
3
var reg = /\d+/g;
var str = 'asdf 34 657 cs33';
console.log(str.match(reg)) // ["34", "657", "33"]
replace()

把’a’替换成 0

1
2
3
//仅第一个a被替换了  
var str = 'abc aaa erv';
console.log(str.replace('a','0')) // 0bc aaa erv
  • replace 配合 字符串去替换字符是非常弱爆的
  • replace只有配合正则才能发挥真正的作用
1
2
3
4
var str = 'abc aaa erv';

var reg = /a/;
console.log(str.replace(reg,'0')) // 0bc aaa erv

但是正则有全局匹配啊

1
2
var reg2 = /a/g;
console.log(str.replace(reg2,'0')) // 0bc 000 erv
replace之敏感词过滤
1
2
3
4
var reg = /零售|中国|淘宝/g;
var str = '淘宝网是亚太地区较大的网络零售、商圈,由阿里巴巴集团在2003年5月创立。淘宝网 [1] 是中国深受欢迎的网购零售平台,拥有近5亿的注册用户数,每天有超过6000万的固定访客,同时每天的在线商品数已经超过了8亿件,平均每分钟售出4.8万件商品';

console.log(str.replace(reg,'**'))

元字符(方括号)

需求匹配 以a或b或c开头+ ‘pc’结尾的字符

1
2
3
[abc]pc
apc bpc cpc √
dpc epc fpc ×
1
2
3
var str = 'apc xpc ppc bpc spc tpc';
var reg = /[abc]pc/g;
console.log(str.match(reg)) // ["apc", "bpc"]

元字符之范围

  • 任意字符 [abc]
  • 范围 [a-z] [0-9]
  • 排除 [^a]
1
2
3
4
[a-z]   a到z的字母
[0-9] 相当于 \d 匹配数字
[^a-z] 除了a到z的字母
[^a-z0-9] 除了a到z的字母和数字

转义字符

1
2
3
4
5
6
7
.  点----任意字符
\d 数字0-9 [0-9]
\w 英文数字下划线 [a-z0-9_]
\s 空白字符
\D 非0-9 [^0-9]
\W 非字母数字下划线 [^a-z0-9_]
\S 非空白字符

偷小说之替换html标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var str = `<p id="p1">fdsadfdssafas</p>
<p class="p2">aaaaaaaaaaaa</p>
<p disabled>bbbbbbbbbbb</p>
<span>ccccccccccc</span>
<div>dddddddddddd</div>
<p>eeeeeeeeeeeee</p>`;

//你肯定想到的是
var reg = /<.+>/g; // 这样会把遇到的第一个 "<"一直匹配到最后一个">"

//实际上应该是除了 "<>"以外

var reg2 = /<[^<>]+>/g;
console.log(str.replace(reg2,''))

量词:个数

1
2
3
4
5
6
7
8
{n} 正好出现n次
{n,m} 最少n次,最多m次
{n,} 最少n次,最多不限

+ <===> {1,}
? <===> {0,1}

* <===> {0,} 可以可无 不推荐使用容易误导
需求1 电话号码 (除去区号010/022/0537)
1
[1-9]\d{7}
需求2 qq号(qq号没有0开头的) 5-11位
1
[1-9]\d{4,10}
需求3 固定电话 010-87490623-86
1
2
3
4
5
6
7
8
9
10
010-87490623-86
010是区号可有可无
86是分机号也是可有可无

前面的区号可有可无 (0\d{2,3}-)?
座机号8位 [1-9]\d{7}
分机号可有可无 (-\d{1,5})?

//最后
(0\d{2,3}-)?[1-9]\d{7}(-\d{1,5})?
为什么不推荐用「*」

因为匹配数字的时候0次也算在内

1
2
3
var str = '12 fff 85 er552 333 -=-=fa22';
console.log(str.match(/\d*/g))
// ["12", "", "", "", "", "", "85", "", "", "", "552", "", "333", "", "", "", "", "", "", "", "22", ""]
行首 「^」行尾「$」

test()

校验是否符合正则返回 true/false

校验邮箱
1
2
3
4
5
6
7
var str = 'trustfor@sina.cn'
var reg = /^\w+@[a-z0-9]+\.[a-z]+$/i;
if(reg.test(str)){
//合法
}else{
//你丫写错了
}